1
0

merge: 合并代码

This commit is contained in:
TsMask
2024-04-30 20:37:27 +08:00
parent 78bd110b03
commit 3cc193f57d
95 changed files with 3028 additions and 1519 deletions

View File

@@ -1,7 +1,7 @@
# 项目信息
framework:
name: "CN EMS"
version: "2.2403.1"
version: "2.2404.6"
# 应用服务配置
server:
@@ -68,6 +68,8 @@ upload:
# 软件包
- ".deb"
- ".rpm"
# 验证文件
- ".ini"
# cors 跨域
cors:

View File

@@ -26,6 +26,9 @@ const (
// 软件包
SOFTWARE = "software"
// 授权文件
LICENSE = "license"
)
// 子路径类型映射
@@ -38,4 +41,5 @@ var UploadSubpath = map[string]string{
DOWNLOAD: "下载",
CHUNK: "切片",
SOFTWARE: "软件包",
LICENSE: "授权文件",
}

View File

@@ -3,6 +3,7 @@ package i18n
import (
"fmt"
"regexp"
"strings"
systemService "be.ems/src/modules/system/service"
)
@@ -70,6 +71,26 @@ func UpdateKeyValue(language, key, value string) bool {
return false
}
// TFindKeyPrefix 翻译值查找键 值前缀匹配
func TFindKeyPrefix(language, keyPrefix, value string) string {
key := value
if value == "" {
return key
}
arr, ok := localeMap[language]
if !ok || len(arr) == 0 {
arr = LoadLocaleData(language)
}
for _, v := range arr {
if strings.HasPrefix(v.Key, keyPrefix) && strings.HasPrefix(v.Value, value) {
key = v.Key
break
}
}
return key
}
// TKey 翻译键
func TKey(language, key string) string {
value := key

View File

@@ -17,6 +17,8 @@ const (
YYYYMMDDHHMMSS = "20060102150405"
// 年-月-日 时:分:秒 列如2022-12-30 01:01:59
YYYY_MM_DD_HH_MM_SS = "2006-01-02 15:04:05"
// 年-月-日T时:分:秒Z时区 列如2022-12-30T01:01:59+08:00
YYYY_MM_DDTHH_MM_SSZ = time.RFC3339
)
// 格式时间字符串

View File

@@ -60,9 +60,12 @@ func uploadWhiteList() []string {
// fileName 原始文件名称含后缀logo.png
func generateFileName(fileName string) string {
fileExt := filepath.Ext(fileName)
// 替换掉后缀和特殊字符保留文件名
// 去除后缀
newFileName := regular.Replace(fileName, fileExt, "")
newFileName = regular.Replace(newFileName, `[<>:"\\|?*]+`, "")
// 去除非法字符
newFileName = regular.Replace(newFileName, `[\\/:*?"<>|]`, "")
// 去除空格
newFileName = regular.Replace(newFileName, `\s`, "_")
newFileName = strings.TrimSpace(newFileName)
return fmt.Sprintf("%s_%s%s", newFileName, generate.Code(6), fileExt)
}

View File

@@ -48,7 +48,7 @@ func ValidMobile(mobile string) bool {
if mobile == "" {
return false
}
pattern := `^1[3|4|5|6|7|8|9][0-9]\d{8}$`
pattern := `^.{3,}$` // `^1[3|4|5|6|7|8|9][0-9]\d{8}$`
match, err := regexp.MatchString(pattern, mobile)
if err != nil {
return false

View File

@@ -5,6 +5,7 @@ import (
"os"
"os/exec"
"path/filepath"
"time"
"be.ems/src/framework/config"
"be.ems/src/framework/logger"
@@ -16,9 +17,9 @@ func FileSCPLocalToNe(neIp, localPath, nePath string) error {
// scp /path/to/local/file.txt user@remote-server:/path/to/remote/directory/
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
cmd := exec.Command("scp", "-r", localPath, neDir)
_, err := cmd.CombinedOutput()
output, err := cmd.CombinedOutput()
if err != nil {
logger.Errorf("FileSCPLocalToNe %s", err.Error())
logger.Errorf("FileSCPLocalToNe %s => %s", output, err.Error())
return err
}
return nil
@@ -31,13 +32,23 @@ func FileSCPNeToLocal(neIp, nePath, localPath string) error {
logger.Errorf("FileSCPNeToLocal MkdirAll err %v", err)
return err
}
// 如果目标文件已经存在,先将目标文件重命名
if info, err := os.Stat(localPath); err == nil && !info.IsDir() {
ext := filepath.Ext(localPath)
name := localPath[0 : len(localPath)-len(ext)]
newName := fmt.Sprintf("%s-%s%s", name, time.Now().Format("20060102_150405"), ext)
err := os.Rename(localPath, newName)
if err != nil {
return err
}
}
usernameNe := config.Get("ne.user").(string)
// scp user@remote-server:/path/to/remote/directory/ /path/to/local/file.txt
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
cmd := exec.Command("scp", "-r", neDir, localPath)
_, err := cmd.CombinedOutput()
output, err := cmd.CombinedOutput()
if err != nil {
logger.Errorf("FileSCPNeToLocal %s", err.Error())
logger.Errorf("FileSCPNeToLocal %s => %s", output, err.Error())
return err
}
return nil

View File

@@ -11,6 +11,7 @@ import (
"time"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/cmd"
gossh "golang.org/x/crypto/ssh"
)
@@ -96,20 +97,11 @@ func (c *ConnSSH) Close() {
func (c *ConnSSH) NewClientByLocalPrivate() (*ConnSSH, error) {
c.Port = 22
c.AuthMode = "1"
usr, err := user.Current()
privateKey, err := c.CurrentUserRsaKey(false)
if err != nil {
logger.Errorf("NewClientByLocal get current user => %s", err.Error())
return nil, err
}
// 读取用户默认的私钥文件
keyPath := fmt.Sprintf("%s/.ssh/id_rsa", usr.HomeDir)
key, err := os.ReadFile(keyPath)
if err != nil {
logger.Errorf("NewClientByLocal [%s] read private key => %s", usr.Username, err.Error())
return nil, err
}
c.PrivateKey = string(key)
c.PrivateKey = privateKey
return c.NewClient()
}
@@ -134,7 +126,55 @@ func (c *ConnSSH) RunCMD(cmd string) (string, error) {
return c.LastResult, err
}
// NewClient 创建SSH客户端会话对象
// SendToAuthorizedKeys 发送当前用户私钥到远程服务器进行授权密钥
func (c *ConnSSH) SendToAuthorizedKeys() error {
publicKey, err := c.CurrentUserRsaKey(true)
if err != nil {
return err
}
authorizedKeysEntry := fmt.Sprintln(strings.TrimSpace(publicKey))
cmdStr := "echo '" + authorizedKeysEntry + "' >> ~/.ssh/authorized_keys"
_, err = c.RunCMD(cmdStr)
if err != nil {
logger.Errorf("SendAuthorizedKeys echo err %s", err.Error())
return err
}
return nil
}
// CurrentUserRsaKey 当前用户OMC使用的RSA私钥
// 默认读取私钥
// ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
// ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub
func (c *ConnSSH) CurrentUserRsaKey(publicKey bool) (string, error) {
usr, err := user.Current()
if err != nil {
logger.Errorf("CurrentUserRsaKey get => %s", err.Error())
return "", err
}
// 是否存在私钥并创建
keyPath := fmt.Sprintf("%s/.ssh/id_rsa", usr.HomeDir)
if _, err := os.Stat(keyPath); err != nil {
_, err2 := cmd.ExecWithCheck("ssh-keygen", "-t", "rsa", "-P", "", "-f", keyPath)
if err2 != nil {
logger.Errorf("CurrentUserPrivateKey ssh-keygen [%s] rsa => %s", usr.Username, err2.Error())
}
}
// 读取用户默认的文件
if publicKey {
keyPath = keyPath + ".pub"
}
key, err := os.ReadFile(keyPath)
if err != nil {
logger.Errorf("CurrentUserRsaKey [%s] read => %s", usr.Username, err.Error())
return "", fmt.Errorf("read file %s fail", keyPath)
}
return string(key), nil
}
// NewClientSession 创建SSH客户端会话对象
func (c *ConnSSH) NewClientSession(cols, rows int) (*SSHClientSession, error) {
sshSession, err := c.Client.NewSession()
if err != nil {

View File

@@ -1,39 +0,0 @@
package libfeatures
import (
"time"
"be.ems/lib/dborm"
"be.ems/lib/oauth"
libConfig "be.ems/restagent/config"
"be.ems/src/framework/logger"
"be.ems/src/framework/redis"
)
// SessionToken 设置登录会话-兼容旧登录方式
func SessionToken(username, sourceAddr string) bool {
// token, _ := redis.Get("", "session_token")
// if token != "" {
// se, err := dborm.XormUpdateSessionShakeTime(token)
// if se.AccountId != username || err != nil {
// // 过期时间单位秒 配置1800是半小时
// expireTime := time.Duration(int64(libConfig.GetExpiresFromConfig())) * time.Second
// redis.SetByExpire("", "session_token", token, expireTime)
// return true
// }
// }
// 不管原先的登录情况直接插入写入覆盖redis中session
//
token := oauth.GenRandToken("omc") // Generate new token to session ID
affected, err := dborm.XormInsertSession(username, sourceAddr, token, libConfig.GetExpiresFromConfig(), libConfig.GetYamlConfig().Auth.Session)
if err != nil {
logger.Errorf("SessionToken XormInsertSession err %v", err)
}
if affected >= 1 {
// 过期时间单位秒 配置1800是半小时
expireTime := time.Duration(int64(libConfig.GetExpiresFromConfig())) * time.Second
redis.SetByExpire("", "session_token", token, expireTime)
return true
}
return false
}

View File

@@ -1,5 +1,4 @@
# 外层 lib 和 features 粘合层
- config.go 配置合并: restagent.yaml 文件内容,主要是数据库配置
- account.go 登录会话生成 token
- session.go 中间件方式设置请求头 token 值

View File

@@ -1,28 +0,0 @@
package session
import (
"time"
libConfig "be.ems/restagent/config"
"be.ems/src/framework/redis"
"github.com/gin-gonic/gin"
)
// SessionHeader 旧登录方式token头
func SessionHeader() gin.HandlerFunc {
return func(c *gin.Context) {
// 读取登录生成的会话token
token, _ := redis.Get("", "session_token")
if token != "" {
// 过期时间单位秒 配置1800是半小时
expireTime := time.Duration(int64(libConfig.GetExpiresFromConfig())) * time.Second
redis.SetByExpire("", "session_token", token, expireTime)
c.Request.Header.Set("Accesstoken", token)
}
// Accesstoken: omc-ce4d0a86-8515-ad51-3249-4913c95f8e34
// 调用下一个处理程序
c.Next()
}
}

View File

@@ -9,7 +9,6 @@ import (
tokenUtils "be.ems/src/framework/utils/token"
"be.ems/src/framework/vo"
"be.ems/src/framework/vo/result"
libAccount "be.ems/src/lib_features/account"
commonModel "be.ems/src/modules/common/model"
commonService "be.ems/src/modules/common/service"
systemService "be.ems/src/modules/system/service"
@@ -83,9 +82,6 @@ func (s *AccountController) Login(c *gin.Context) {
)
}
// 设置登录会话-兼容旧登录方式
libAccount.SessionToken(loginBody.Username, ipaddr)
c.JSON(200, result.OkData(map[string]any{
tokenConstants.RESPONSE_FIELD: tokenStr,
}))

View File

@@ -25,8 +25,9 @@ type BarProcessor struct {
type BarParams struct {
Duration int `json:"duration"`
TableName string `json:"tableName"`
ColName string `json:"colName"` // column name of time string
Extras string `json:"extras"` // extras condition for where
ColName string `json:"colName"` // column name of time string
Extras string `json:"extras"` // extras condition for where
SessFlag bool `json:"sessFlag"` // session flag, true: session model, false: no session
}
func (s *BarProcessor) Execute(data any) (any, error) {
@@ -74,10 +75,19 @@ func (s *BarProcessor) Execute(data any) (any, error) {
where = fmt.Sprintf("NOW()>ADDDATE(`%s`,interval %d day) and %s", params.ColName, params.Duration, params.Extras)
}
affected, err := dborm.XormDeleteDataByWhere(where, params.TableName)
if err != nil {
// panic(fmt.Sprintf("Failed to XormDeleteDataByWhere:%v", err))
return nil, err
var affected int64 = 0
if params.SessFlag {
affected, err = dborm.XormDeleteDataByWhere(where, params.TableName)
if err != nil {
// panic(fmt.Sprintf("Failed to XormDeleteDataByWhere:%v", err))
return nil, err
}
} else {
affected, err = dborm.XormDeleteDataByWhereNoSession(where, params.TableName)
if err != nil {
// panic(fmt.Sprintf("Failed to XormDeleteDataByWhere:%v", err))
return nil, err
}
}
// 返回结果,用于记录执行结果

View File

@@ -112,7 +112,8 @@ func (s *BarProcessor) Execute(data any) (any, error) {
for _, ne := range nes {
//log.Debug("ne:", ne)
sql := fmt.Sprintf("select * from ne_state where ne_type = '%s' and ne_id = '%s' order by timestamp desc limit 1", ne.NeType, ne.NeId)
sql := fmt.Sprintf("select * from ne_state where ne_type='%s' and ne_id='%s' order by `timestamp` desc limit 1", ne.NeType, ne.NeId)
log.Debug("SQL:", sql)
neState, err := dborm.XormGetDataBySQL(sql)
if err != nil {
log.Error("Failed to get ne_state:", err)
@@ -120,7 +121,7 @@ func (s *BarProcessor) Execute(data any) (any, error) {
}
if len(*neState) == 0 {
log.Warn("Not found record in ne_state:")
continue
//continue
}
//log.Debug("neState:", *neState)
@@ -149,7 +150,7 @@ func (s *BarProcessor) Execute(data any) (any, error) {
var timestamp string
if len(*neState) == 0 {
log.Infof("Not found ne_state neType:%s, neId:%s", ne.NeType, ne.NeId)
timestamp = ne.UpdateTime
timestamp = ne.UpdateTime.Format(time.DateTime)
} else {
timestamp = (*neState)[0]["timestamp"]
}
@@ -201,11 +202,13 @@ func (s *BarProcessor) Execute(data any) (any, error) {
var response *resty.Response
requestURI := fmt.Sprintf("/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", ne.NeType)
restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
//restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
restHost := config.GetOMCHostUrl()
requestURL := fmt.Sprintf("%s%s", restHost, requestURI)
log.Debug("requestURL: POST ", requestURL)
response, err = client.R().
EnableTrace().
//SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
SetBody(body).
@@ -268,7 +271,8 @@ func (s *BarProcessor) Execute(data any) (any, error) {
var response *resty.Response
requestURI := fmt.Sprintf("/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", ne.NeType)
restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
//restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
restHost := config.GetOMCHostUrl()
requestURL := fmt.Sprintf("%s%s", restHost, requestURI)
log.Debug("requestURL: POST ", requestURL)
response, err = client.R().

View File

@@ -116,17 +116,20 @@ func (s *BarProcessor) Execute(data any) (any, error) {
log.Trace("response body:", string(response.Body()))
state := new(SystemState)
_ = json.Unmarshal(response.Body(), &state)
var dateStr *string = nil
if state.ExpiryDate != "" && state.ExpiryDate != "-" {
dateStr = &state.ExpiryDate
}
// var dateStr *string = nil
// if state.ExpiryDate != "" && state.ExpiryDate != "-" {
// dateStr = &state.ExpiryDate
// }
neState := new(dborm.NeState)
neState.NeType = ne.NeType
neState.NeId = ne.NeId
neState.Version = state.Version
neState.Capability = state.Capability
neState.SerialNum = state.SerialNum
neState.ExpiryDate = *dateStr
// if dateStr != nil {
// neState.ExpiryDate = *dateStr
// }
neState.ExpiryDate = state.ExpiryDate
cu, _ := json.Marshal(state.CpuUsage)
neState.CpuUsage = string(cu)
mu, _ := json.Marshal(state.MemUsage)

View File

@@ -40,12 +40,17 @@ type SysJobController struct {
//
// GET /list
func (s *SysJobController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
data := s.sysJobService.SelectJobPage(querys)
rows := data["rows"].([]model.SysJob)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
querys := ctx.QueryMap(c)
// 多语言值转key查询
if v, ok := querys["jobName"]; ok && v != "" {
querys["jobName"] = i18n.TFindKeyPrefix(language, "job", v.(string))
}
data := s.sysJobService.SelectJobPage(querys)
rows := data["rows"].([]model.SysJob)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysJob) {
for i := range *arr {
(*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName)
@@ -314,14 +319,21 @@ func (s *SysJobController) ResetQueueJob(c *gin.Context) {
func (s *SysJobController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
data := s.sysJobService.SelectJobPage(querys)
if data["total"].(int64) == 0 {
// querys := ctx.BodyJSONMap(c)
// data := s.sysJobService.SelectJobPage(querys)
// if data["total"].(int64) == 0 {
// // 导出数据记录为空
// c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
// return
// }
// rows := data["rows"].([]model.SysJob)
rows := s.sysJobService.SelectJobList(model.SysJob{})
if len(rows) <= 0 {
// 导出数据记录为空
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
return
}
rows := data["rows"].([]model.SysJob)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysJob) {
@@ -340,10 +352,10 @@ func (s *SysJobController) Export(c *gin.Context) {
"B1": i18n.TKey(language, "job.export.jobName"),
"C1": i18n.TKey(language, "job.export.jobGroupName"),
"D1": i18n.TKey(language, "job.export.invokeTarget"),
"E1": i18n.TKey(language, "job.export.targetParams"),
"F1": i18n.TKey(language, "job.export.cronExpression"),
"G1": i18n.TKey(language, "job.export.status"),
"H1": i18n.TKey(language, "job.export.remark"),
"E1": i18n.TKey(language, "job.export.cronExpression"),
"F1": i18n.TKey(language, "job.export.status"),
"G1": i18n.TKey(language, "job.export.remark"),
// "E1": i18n.TKey(language, "job.export.targetParams"),
}
// 读取任务组名字典数据
dictSysJobGroup := s.sysDictDataService.SelectDictDataByType("sys_job_group")
@@ -370,10 +382,10 @@ func (s *SysJobController) Export(c *gin.Context) {
"B" + idx: row.JobName,
"C" + idx: sysJobGroup,
"D" + idx: row.InvokeTarget,
"E" + idx: row.TargetParams,
"F" + idx: row.CronExpression,
"G" + idx: statusValue,
"H" + idx: row.Remark,
"E" + idx: row.CronExpression,
"F" + idx: statusValue,
"G" + idx: row.Remark,
// "E" + idx: row.TargetParams,
})
}

View File

@@ -39,6 +39,7 @@ type SysJobLogController struct {
//
// GET /list
func (s *SysJobLogController) List(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询参数转换map
querys := ctx.QueryMap(c)
// 任务ID优先级更高
@@ -47,11 +48,15 @@ func (s *SysJobLogController) List(c *gin.Context) {
querys["jobName"] = jobInfo.JobName
querys["jobGroup"] = jobInfo.JobGroup
}
data := s.sysJobLogService.SelectJobLogPage(querys)
// 多语言值转key查询
if v, ok := querys["jobName"]; ok && v != "" {
querys["jobName"] = i18n.TFindKeyPrefix(language, "job", v.(string))
}
data := s.sysJobLogService.SelectJobLogPage(querys)
rows := data["rows"].([]model.SysJobLog)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
converI18n := func(language string, arr *[]model.SysJobLog) {
for i := range *arr {
(*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName)
@@ -124,17 +129,24 @@ func (s *SysJobLogController) Clean(c *gin.Context) {
//
// POST /export
func (s *SysJobLogController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
data := s.sysJobLogService.SelectJobLogPage(querys)
if data["total"].(int64) == 0 {
c.JSON(200, result.ErrMsg("Export data record is empty"))
// querys := ctx.BodyJSONMap(c)
// data := s.sysJobLogService.SelectJobLogPage(querys)
// if data["total"].(int64) == 0 {
// c.JSON(200, result.ErrMsg("Export data record is empty"))
// return
// }
// rows := data["rows"].([]model.SysJobLog)
rows := s.sysJobLogService.SelectJobLogList(model.SysJobLog{})
if len(rows) <= 0 {
// 导出数据记录为空
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
return
}
rows := data["rows"].([]model.SysJobLog)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
converI18n := func(language string, arr *[]model.SysJobLog) {
for i := range *arr {
(*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName)
@@ -150,10 +162,11 @@ func (s *SysJobLogController) Export(c *gin.Context) {
"B1": i18n.TKey(language, "job.export.jobName"),
"C1": i18n.TKey(language, "job.export.jobGroupName"),
"D1": i18n.TKey(language, "job.export.invokeTarget"),
"E1": i18n.TKey(language, "job.export.targetParams"),
"F1": i18n.TKey(language, "job.export.jobID"),
"G1": i18n.TKey(language, "job.export.jobLogStatus"),
"H1": i18n.TKey(language, "job.export.jobLogTime"),
// "E1": i18n.TKey(language, "job.export.targetParams"),
// "F1": i18n.TKey(language, "job.export.jobID"),
"E1": i18n.TKey(language, "job.export.jobLogStatus"),
"F1": i18n.TKey(language, "job.export.jobLogTime"),
"G1": i18n.TKey(language, "log.operate.export.costTime"),
}
// 读取任务组名字典数据
dictSysJobGroup := s.sysDictDataService.SelectDictDataByType("sys_job_group")
@@ -179,10 +192,11 @@ func (s *SysJobLogController) Export(c *gin.Context) {
"B" + idx: row.JobName,
"C" + idx: sysJobGroup,
"D" + idx: row.InvokeTarget,
"E" + idx: row.TargetParams,
"F" + idx: row.JobMsg,
"G" + idx: statusValue,
"H" + idx: date.ParseDateToStr(row.CreateTime, date.YYYY_MM_DD_HH_MM_SS),
// "E" + idx: row.TargetParams,
// "F" + idx: row.JobMsg,
"E" + idx: statusValue,
"F" + idx: date.ParseDateToStr(row.CreateTime, date.YYYY_MM_DD_HH_MM_SS),
"G" + idx: row.CostTime,
})
}

View File

@@ -6,7 +6,6 @@ import (
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/repo"
"be.ems/src/modules/monitor/model"
@@ -80,8 +79,7 @@ func (r *SysJobLogImpl) SelectJobLogPage(query map[string]any) map[string]any {
}
if ok && beginTime != "" {
conditions = append(conditions, "create_time >= ?")
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
params = append(params, beginDate.UnixMilli())
params = append(params, parse.Number(beginTime.(string)))
}
endTime, ok := query["endTime"]
if !ok {
@@ -89,8 +87,7 @@ func (r *SysJobLogImpl) SelectJobLogPage(query map[string]any) map[string]any {
}
if ok && endTime != "" {
conditions = append(conditions, "create_time <= ?")
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
params = append(params, endDate.UnixMilli())
params = append(params, parse.Number(endTime.(string)))
}
// 构建查询条件语句

View File

@@ -354,3 +354,53 @@ func (s *NeHostController) CheckBySSH(c *gin.Context) {
c.JSON(200, result.OkData(data))
}
// 网元主机SSH方式授权免密发送
//
// POST /authorizedBySSH
func (s *NeHostController) AuthorizedBySSH(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body model.NeHost
err := c.ShouldBindBodyWith(&body, binding.JSON)
if err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 本地免密创建链接直连
sshLink := false
lcoalConnSSH := ssh.ConnSSH{
User: body.User,
Addr: body.Addr,
Port: body.Port,
}
lcoalClient, err := lcoalConnSSH.NewClientByLocalPrivate()
if err == nil {
sshLink = true
}
defer lcoalClient.Close()
if sshLink {
// 连接主机成功,无需重复免密授权认证
c.JSON(200, result.OkMsg(i18n.TKey(language, "neHost.okBySSHLink")))
return
}
// 创建链接SSH客户端
var connSSH ssh.ConnSSH
body.CopyTo(&connSSH)
client, err := connSSH.NewClient()
if err != nil {
// 连接主机失败,请检查连接参数后重试
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo")))
return
}
defer client.Close()
// 发送密钥
err = client.SendToAuthorizedKeys()
if err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
}
c.JSON(200, result.Ok(nil))
}

View File

@@ -39,15 +39,15 @@ func (s *NeInfoController) State(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType" binding:"required"`
NeID string `form:"neId" binding:"required"`
NeId string `form:"neId" binding:"required"`
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
if neInfo.NeId != querys.NeID || neInfo.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
}
@@ -84,17 +84,26 @@ func (s *NeInfoController) State(c *gin.Context) {
c.JSON(200, result.OkData(resData))
}
// 网元信息列表
// 网元neType和neID查询
//
// GET /list
func (s *NeInfoController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
bandStatus := false
if v, ok := querys["bandStatus"]; ok && v != nil {
bandStatus = parse.Boolean(v)
// GET /byTypeAndID
func (s *NeInfoController) NeTypeAndID(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType" binding:"required"`
NeID string `form:"neId" binding:"required"`
}
data := s.neInfoService.SelectPage(querys, bandStatus)
c.JSON(200, result.Ok(data))
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
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
}
c.JSON(200, result.OkData(neInfo))
}
// 网元信息列表全部无分页
@@ -129,6 +138,85 @@ func (s *NeInfoController) ListAll(c *gin.Context) {
c.JSON(200, result.OkData(neList))
}
// 网元端配置文件读取
//
// GET /configFile
func (s *NeInfoController) ConfigFileRead(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType" binding:"required"`
NeID string `form:"neId" binding:"required"`
FilePath string `form:"filePath"` // 不带文件路径时进行复制覆盖本地网元配置目录
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 查询网元获取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
}
data := s.neInfoService.NeConfigFileRead(neInfo, querys.FilePath)
if querys.FilePath == "" {
c.JSON(200, result.OkData(data))
return
}
if len(data) > 0 {
c.JSON(200, result.OkData(data[0]))
return
}
c.JSON(200, result.ErrMsg("no data"))
}
// 网元端配置文件写入
//
// PUT /configFile
func (s *NeInfoController) ConfigFileWrite(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body struct {
NeType string `json:"neType" binding:"required"`
NeID string `json:"neId" binding:"required"`
FilePath string `json:"filePath" binding:"required"`
Content string `json:"content" binding:"required"`
Sync bool `json:"sync"`
}
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 查询网元获取IP
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeID)
if neInfo.NeId != body.NeID || neInfo.IP == "" {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
return
}
err := s.neInfoService.NeConfigFileWirte(neInfo, body.FilePath, body.Content, body.Sync)
if err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
}
c.JSON(200, result.Ok(nil))
}
// 网元信息列表
//
// GET /list
func (s *NeInfoController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
bandStatus := false
if v, ok := querys["bandStatus"]; ok && v != nil {
bandStatus = parse.Boolean(v)
}
data := s.neInfoService.SelectPage(querys, bandStatus)
c.JSON(200, result.Ok(data))
}
// 网元信息
//
// GET /:infoId
@@ -150,28 +238,6 @@ func (s *NeInfoController) Info(c *gin.Context) {
c.JSON(200, result.OkData(neHost))
}
// 网元neType和neID查询
//
// GET /
func (s *NeInfoController) NeTypeAndID(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType" binding:"required"`
NeID string `form:"neId" binding:"required"`
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
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
}
c.JSON(200, result.OkData(neInfo))
}
// 网元信息新增
//
// POST /

View File

@@ -0,0 +1,301 @@
package controller
import (
"fmt"
"strings"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/network_element/model"
neService "be.ems/src/modules/network_element/service"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
// 实例化控制层 NeLicenseController 结构体
var NewNeLicense = &NeLicenseController{
neLicenseService: neService.NewNeLicenseImpl,
neInfoService: neService.NewNeInfoImpl,
}
// 网元授权激活信息请求
//
// PATH /license
type NeLicenseController struct {
// 网元授权激活信息服务
neLicenseService neService.INeLicense
// 网元信息服务
neInfoService neService.INeInfo
}
// 网元授权激活信息列表
//
// GET /list
func (s *NeLicenseController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
data := s.neLicenseService.SelectPage(querys)
c.JSON(200, result.Ok(data))
}
// 网元授权激活信息
//
// GET /:licenseId
func (s *NeLicenseController) Info(c *gin.Context) {
language := ctx.AcceptLanguage(c)
licenseId := c.Param("licenseId")
if licenseId == "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
neLicense := s.neLicenseService.SelectById(licenseId)
if neLicense.ID != licenseId {
// 没有可访问网元授权激活数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData")))
return
}
c.JSON(200, result.OkData(neLicense))
}
// 网元授权激活信息新增
//
// POST /
func (s *NeLicenseController) Add(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body model.NeLicense
err := c.ShouldBindBodyWith(&body, binding.JSON)
if err != nil || body.ID != "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 查询网元获取IP
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeId)
if neInfo.NeId != body.NeId || neInfo.IP == "" {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
return
}
// 检查属性值唯一
uniqueInfo := s.neLicenseService.CheckUniqueTypeAndID(neInfo.NeType, neInfo.NeId, "")
if !uniqueInfo {
// 网元授权激活操作【%s】失败网元类型信息已存在
msg := i18n.TTemplate(language, "neLicense.errKeyExists", map[string]any{"name": neInfo.NeType})
c.JSON(200, result.ErrMsg(msg))
return
}
// 读取授权码
code, _ := s.neLicenseService.ReadLicenseInfo(neInfo)
body.ActivationRequestCode = code
body.CreateBy = ctx.LoginUserToUserName(c)
insertId := s.neLicenseService.Insert(body)
if insertId != "" {
c.JSON(200, result.Ok(nil))
return
}
c.JSON(200, result.Err(nil))
}
// 网元授权激活信息修改
//
// PUT /
func (s *NeLicenseController) Edit(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body model.NeLicense
err := c.ShouldBindBodyWith(&body, binding.JSON)
if err != nil || body.ID == "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 检查属性值唯一
uniqueInfo := s.neLicenseService.CheckUniqueTypeAndID(body.NeType, body.NeId, body.ID)
if !uniqueInfo {
// 网元授权激活操作【%s】失败网元类型信息已存在
msg := i18n.TTemplate(language, "neLicense.errKeyExists", map[string]any{"name": body.NeType})
c.JSON(200, result.ErrMsg(msg))
return
}
// 检查是否存在
neLicense := s.neLicenseService.SelectById(body.ID)
if neLicense.ID != body.ID {
// 没有可访问网元授权激活数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData")))
return
}
body.UpdateBy = ctx.LoginUserToUserName(c)
rows := s.neLicenseService.Update(body)
if rows > 0 {
c.JSON(200, result.Ok(nil))
return
}
c.JSON(200, result.Err(nil))
}
// 网元授权激活信息删除
//
// DELETE /:licenseIds
func (s *NeLicenseController) Remove(c *gin.Context) {
language := ctx.AcceptLanguage(c)
licenseIds := c.Param("licenseIds")
if licenseIds == "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 处理字符转id数组后去重
ids := strings.Split(licenseIds, ",")
uniqueIDs := parse.RemoveDuplicates(ids)
if len(uniqueIDs) <= 0 {
c.JSON(200, result.Err(nil))
return
}
rows, err := s.neLicenseService.DeleteByIds(uniqueIDs)
if err != nil {
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
return
}
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
c.JSON(200, result.OkMsg(msg))
}
// 网元授权激活授权申请码
//
// GET /code
func (s *NeLicenseController) Code(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType" binding:"required"`
NeId string `form:"neId" binding:"required"`
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 查询网元获取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
}
// 检查是否存在授权记录
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
if neLicense.NeId != querys.NeId {
// 没有可访问网元授权激活数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData")))
return
}
// 更新授权码
code, licensePath := s.neLicenseService.ReadLicenseInfo(neInfo)
neLicense.ActivationRequestCode = code
if licensePath != "" {
neLicense.LicensePath = licensePath
} else {
neLicense.SerialNum = ""
neLicense.ExpiryDate = ""
neLicense.Status = "0"
}
neLicense.UpdateBy = ctx.LoginUserToUserName(c)
s.neLicenseService.Update(neLicense)
c.JSON(200, result.OkData(code))
}
// 网元授权激活授权文件替换
//
// POST /change
func (s *NeLicenseController) Change(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body model.NeLicense
err := c.ShouldBindBodyWith(&body, binding.JSON)
if err != nil || body.HostId == "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 检查是否存在授权记录
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(body.NeType, body.NeId)
if neLicense.NeId != body.NeId {
body.Status = "0"
body.CreateBy = ctx.LoginUserToUserName(c)
body.ID = s.neLicenseService.Insert(body)
} else {
neLicense.LicensePath = body.LicensePath
neLicense.Status = "0"
neLicense.UpdateBy = ctx.LoginUserToUserName(c)
s.neLicenseService.Update(neLicense)
}
// 进行上传替换
err = s.neLicenseService.UploadToNeHost(body)
if err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
}
c.JSON(200, result.Ok(nil))
}
// 网元授权激活状态
//
// GET /state
func (s *NeLicenseController) State(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType" binding:"required"`
NeId string `form:"neId" binding:"required"`
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 查询网元获取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
}
// 检查是否存在授权记录
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
if neLicense.NeId != querys.NeId {
// 没有可访问网元授权激活数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData")))
return
}
// 查询网元状态
neState, err := neService.NeState(neInfo)
if err != nil {
c.JSON(200, result.ErrMsg("network element service anomaly"))
return
}
// 更新授权信息
neLicense.SerialNum = fmt.Sprint(neState["sn"])
neLicense.ExpiryDate = fmt.Sprint(neState["expire"])
code, licensePath := s.neLicenseService.ReadLicenseInfo(neInfo)
neLicense.ActivationRequestCode = code
neLicense.LicensePath = licensePath
neLicense.Status = "1"
neLicense.UpdateBy = ctx.LoginUserToUserName(c)
rows := s.neLicenseService.Update(neLicense)
if rows > 0 {
c.JSON(200, result.OkData(map[string]string{
"sn": neLicense.SerialNum,
"expire": neLicense.ExpiryDate,
}))
return
}
c.JSON(200, result.Err(nil))
}

View File

@@ -49,7 +49,7 @@ func (s *NeSoftwareController) Info(c *gin.Context) {
neSoftware := s.neSoftwareService.SelectById(softwareId)
if neSoftware.ID != softwareId {
// 没有可访问网元版本数据!
// 没有可访问网元包信息数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData")))
return
}
@@ -64,20 +64,21 @@ func (s *NeSoftwareController) Add(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body model.NeSoftware
err := c.ShouldBindBodyWith(&body, binding.JSON)
if err != nil || body.ID != "" {
if err != nil || body.Path == "" || body.ID != "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 检查属性值唯一
uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndFileNameAndVersion(body.NeType, body.FileName, body.Version, "")
uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndNameAndVersion(body.NeType, body.Name, body.Version, "")
if !uniqueSoftware {
// 网元软件包操作【%s】失败网元类型与文件名版本已存在
msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.FileName})
msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.Name})
c.JSON(200, result.ErrMsg(msg))
return
}
body.CreateBy = ctx.LoginUserToUserName(c)
insertId := s.neSoftwareService.Insert(body)
if insertId != "" {
c.JSON(200, result.Ok(nil))
@@ -93,16 +94,16 @@ func (s *NeSoftwareController) Edit(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body model.NeSoftware
err := c.ShouldBindBodyWith(&body, binding.JSON)
if err != nil || body.ID == "" {
if err != nil || body.Path == "" || body.ID == "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 检查属性值唯一
uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndFileNameAndVersion(body.NeType, body.FileName, body.Version, body.ID)
uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndNameAndVersion(body.NeType, body.Name, body.Version, body.ID)
if !uniqueSoftware {
// 网元软件包操作【%s】失败网元类型与文件名版本已存在
msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.FileName})
msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.Name})
c.JSON(200, result.ErrMsg(msg))
return
}
@@ -110,11 +111,12 @@ func (s *NeSoftwareController) Edit(c *gin.Context) {
// 检查是否存在
neSoftware := s.neSoftwareService.SelectById(body.ID)
if neSoftware.ID != body.ID {
// 没有可访问网元版本数据!
// 没有可访问网元包信息数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData")))
return
}
body.UpdateBy = ctx.LoginUserToUserName(c)
rows := s.neSoftwareService.Update(body)
if rows > 0 {
c.JSON(200, result.Ok(nil))
@@ -149,32 +151,40 @@ func (s *NeSoftwareController) Remove(c *gin.Context) {
c.JSON(200, result.OkMsg(msg))
}
// 网元软件包安装
// 网元软件包安装检查
//
// POST /install
func (s *NeSoftwareController) Install(c *gin.Context) {
// POST /checkInstall
func (s *NeSoftwareController) CheckInstall(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body model.NeSoftware
err := c.ShouldBindBodyWith(&body, binding.JSON)
if err != nil {
if err != nil || body.HostId == "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 检查是否存在
neSoftwares := s.neSoftwareService.SelectList(body)
if len(neSoftwares) == 0 {
// 没有可访问网元版本数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData")))
return
// 检查是否存在软件包记录
neSoftwares := s.neSoftwareService.SelectList(model.NeSoftware{
NeType: body.NeType,
Name: body.Name,
Version: body.Version,
})
if len(neSoftwares) <= 0 {
body.CreateBy = ctx.LoginUserToUserName(c)
body.ID = s.neSoftwareService.Insert(body)
} else {
neSoftware := neSoftwares[0]
neSoftware.Path = body.Path
neSoftware.Description = body.Description
neSoftware.UpdateBy = ctx.LoginUserToUserName(c)
s.neSoftwareService.Update(neSoftware)
}
neSoftware := neSoftwares[0]
// 进行安装
output, err := s.neSoftwareService.Install(neSoftware)
// 进行安装检查
cmdStrArr, err := s.neSoftwareService.UploadToNeHost(body)
if err != nil {
c.JSON(200, result.OkData(output))
c.JSON(200, result.ErrMsg(err.Error()))
return
}
c.JSON(200, result.Err(nil))
c.JSON(200, result.OkData(cmdStrArr))
}

View File

@@ -78,6 +78,7 @@ func (s *NeVersionController) Add(c *gin.Context) {
return
}
body.CreateBy = ctx.LoginUserToUserName(c)
insertId := s.neVersionService.Insert(body)
if insertId != "" {
c.JSON(200, result.Ok(nil))
@@ -115,6 +116,7 @@ func (s *NeVersionController) Edit(c *gin.Context) {
return
}
body.UpdateBy = ctx.LoginUserToUserName(c)
rows := s.neVersionService.Update(body)
if rows > 0 {
c.JSON(200, result.Ok(nil))

View File

@@ -0,0 +1,28 @@
package model
// NeLicense 网元授权激活信息 ne_license
type NeLicense struct {
ID string `json:"id" gorm:"id"`
NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型
NeId string `json:"neId" gorm:"ne_id" binding:"required"` // 网元ID
ActivationRequestCode string `json:"activationRequestCode" gorm:"activation_request_code"` // 激活申请代码
LicensePath string `json:"licensePath" gorm:"license_path"` // 激活授权文件
SerialNum string `json:"serialNum" gorm:"serial_num"` // 序列号
ExpiryDate string `json:"expiryDate" gorm:"expiry_date"` // 许可证到期日期
Status string `json:"status" gorm:"status"` // 状态 ''ACTIVE'',''INACTIVE'',''PENDING''
Remark string `json:"remark" gorm:"remark"` // 备注
CreateBy string `json:"createBy" gorm:"create_by"` // 创建者
CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间
UpdateBy string `json:"updateBy" gorm:"update_by"` // 更新者
UpdateTime int64 `json:"updateTime" gorm:"update_time"` // 更新时间
// ====== 非数据库字段属性 ======
Reload bool `json:"reload,omitempty" gorm:"-"` // 刷新重启网元
HostId string `json:"hostId,omitempty" gorm:"-"` // 已记录的主机ID
}
// TableName 表名称
func (*NeLicense) TableName() string {
return "ne_license"
}

View File

@@ -1,18 +1,21 @@
package model
import "time"
// NeSoftware 网元软件包 ne_software
type NeSoftware struct {
ID string `json:"id" gorm:"id"`
NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型
FileName string `json:"fileName" gorm:"file_name" binding:"required"` // 包名称
Path string `json:"path" gorm:"path"` // 包路径
Version string `json:"version" gorm:"version" binding:"required"` // 包版本
Md5Sum string `json:"md5Sum" gorm:"md5_sum"` // --无使用 md5签名
Status string `json:"status" gorm:"status"` // --无使用
Comment string `json:"comment" gorm:"comment"` // 包说明
UpdateTime time.Time `json:"updateTime" gorm:"update_time"` // 上传时间
ID string `json:"id" gorm:"id"`
NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型
Name string `json:"name" gorm:"name" binding:"required"` // 包名称
Path string `json:"path" gorm:"path"` // 包路径
Version string `json:"version" gorm:"version" binding:"required"` // 包版本
Description string `json:"description" gorm:"description"` // 包说明
CreateBy string `json:"createBy" gorm:"column:create_by"` // 创建者
CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间
UpdateBy string `json:"updateBy" gorm:"column:update_by"` // 更新者
UpdateTime int64 `json:"updateTime" gorm:"column:update_time"` // 更新时间
// ====== 非数据库字段属性 ======
HostId string `json:"hostId,omitempty" gorm:"-"` // 已记录的主机ID
}
// TableName 表名称

View File

@@ -1,20 +1,21 @@
package model
import "time"
// NeVersion 网元版本信息 ne_version
type NeVersion struct {
ID string `json:"id" gorm:"id"`
NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型
NeId string `json:"neId" gorm:"ne_id" binding:"required"` // 网元ID
Version string `json:"version" gorm:"version"` // 当前版本
FilePath string `json:"filePath" gorm:"file_path"` // 当前软件包
PreVersion string `json:"preVersion" gorm:"pre_version"` // 上一版本
PreFile string `json:"preFile" gorm:"pre_file"` // 上一版本软件包
NewVersion string `json:"newVersion" gorm:"new_version"` // 下一版本
NewFile string `json:"newFile" gorm:"new_file"` // 下一版本软件包
Status string `json:"status" gorm:"status" binding:"oneof=Uploaded Inactive Active"` // 当前状态 (Uploaded下一版本上传 Inactive下一版本待激活 Active当前已激活)
UpdateTime time.Time `json:"updateTime" gorm:"update_time"` // 更新时间
ID string `json:"id" gorm:"id"`
NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型
NeId string `json:"neId" gorm:"ne_id" binding:"required"` // 网元ID
Version string `json:"version" gorm:"version" binding:"required"` // 当前版本
Path string `json:"path" gorm:"path" binding:"required"` // 当前软件包
PreVersion string `json:"preVersion" gorm:"pre_version"` // 上一版本
PrePath string `json:"prePath" gorm:"pre_path"` // 上一版本软件包
NewVersion string `json:"newVersion" gorm:"new_version"` // 下一版本
NewPath string `json:"newPath" gorm:"new_path"` // 下一版本软件包
Status string `json:"status" gorm:"status"` // 当前状态 (Uploaded下一版本上传 Inactive下一版本待激活 Active当前已激活)
CreateBy string `json:"createBy" gorm:"column:create_by"` // 创建者
CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间
UpdateBy string `json:"updateBy" gorm:"column:update_by"` // 更新者
UpdateTime int64 `json:"updateTime" gorm:"column:update_time"` // 更新时间
}
// TableName 表名称

View File

@@ -2,14 +2,14 @@ package model
// UDMAuth UDM鉴权用户对象 u_auth_user
type UDMAuth struct {
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
Imsi string `json:"imsi" gorm:"column:imsi"` // SIM卡号
Amf string `json:"amf" gorm:"column:amf"` // ANF
Status string `json:"status" gorm:"column:status"` // 状态
Ki string `json:"ki" gorm:"column:ki"` // ki
AlgoIndex string `json:"algoIndex" gorm:"column:algo_index"` // AlgoIndex
Opc string `json:"opc" gorm:"column:opc"`
NeID string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 默认ID
Imsi string `json:"imsi" gorm:"column:imsi"` // SIM卡号
Amf string `json:"amf" gorm:"column:amf"` // ANF
Status string `json:"status" gorm:"column:status"` // 状态
Ki string `json:"ki" gorm:"column:ki"` // ki
AlgoIndex string `json:"algoIndex" gorm:"column:algo_index"` // AlgoIndex
Opc string `json:"opc" gorm:"column:opc"` // opc
NeID string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统
}
func (UDMAuth) TableName() string {

View File

@@ -25,6 +25,8 @@ type UDMSub struct {
ApnContext string `json:"apnContext" gorm:"column:apn_context"`
StaticIp string `json:"staticIp" gorm:"column:static_ip"`
// ====== 非数据库字段属性 ======
SubNum string `json:"subNum,omitempty" gorm:"-"` // 批量数
}

View File

@@ -41,10 +41,26 @@ func Setup(router *gin.Engine) {
// 网元信息
neInfoGroup := neGroup.Group("/info")
{
neInfoGroup.GET("/state",
middleware.PreAuthorize(nil),
controller.NewNeInfo.State,
)
neInfoGroup.GET("/byTypeAndID",
middleware.PreAuthorize(nil),
controller.NewNeInfo.NeTypeAndID,
)
neInfoGroup.GET("/listAll",
middleware.PreAuthorize(nil),
controller.NewNeInfo.ListAll,
)
neInfoGroup.GET("/configFile",
middleware.PreAuthorize(nil),
controller.NewNeInfo.ConfigFileRead,
)
neInfoGroup.PUT("/configFile",
middleware.PreAuthorize(nil),
controller.NewNeInfo.ConfigFileWrite,
)
neInfoGroup.GET("/list",
middleware.PreAuthorize(nil),
controller.NewNeInfo.List,
@@ -68,14 +84,6 @@ func Setup(router *gin.Engine) {
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neInfo", collectlogs.BUSINESS_TYPE_DELETE)),
controller.NewNeInfo.Remove,
)
neInfoGroup.GET("/state",
middleware.PreAuthorize(nil),
controller.NewNeInfo.State,
)
neInfoGroup.GET("/byTypeAndID",
middleware.PreAuthorize(nil),
controller.NewNeInfo.NeTypeAndID,
)
}
// 网元主机
@@ -119,6 +127,11 @@ func Setup(router *gin.Engine) {
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neHost", collectlogs.BUSINESS_TYPE_OTHER)),
controller.NewNeHost.CheckBySSH,
)
neHostGroup.POST("/authorizedBySSH",
middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neHost", collectlogs.BUSINESS_TYPE_OTHER)),
controller.NewNeHost.AuthorizedBySSH,
)
}
// 网元主机命令
@@ -203,10 +216,51 @@ func Setup(router *gin.Engine) {
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neSoftware", collectlogs.BUSINESS_TYPE_DELETE)),
controller.NewNeSoftware.Remove,
)
neSoftwareGroup.POST("/install",
neSoftwareGroup.POST("/checkInstall",
middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neSoftware", collectlogs.BUSINESS_TYPE_DELETE)),
controller.NewNeSoftware.Install,
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neSoftware", collectlogs.BUSINESS_TYPE_OTHER)),
controller.NewNeSoftware.CheckInstall,
)
}
// 网元授权激活信息
neLicenseGroup := neGroup.Group("/license")
{
neLicenseGroup.GET("/list",
middleware.PreAuthorize(nil),
controller.NewNeLicense.List,
)
neLicenseGroup.GET("/:licenseId",
middleware.PreAuthorize(nil),
controller.NewNeLicense.Info,
)
neLicenseGroup.POST("",
middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_INSERT)),
controller.NewNeLicense.Add,
)
neLicenseGroup.PUT("",
middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_UPDATE)),
controller.NewNeLicense.Edit,
)
neLicenseGroup.DELETE("/:licenseIds",
middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_DELETE)),
controller.NewNeLicense.Remove,
)
neLicenseGroup.GET("/code",
middleware.PreAuthorize(nil),
controller.NewNeLicense.Code,
)
neLicenseGroup.POST("/change",
middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_OTHER)),
controller.NewNeLicense.Change,
)
neLicenseGroup.GET("/state",
middleware.PreAuthorize(nil),
controller.NewNeLicense.State,
)
}

View File

@@ -29,6 +29,7 @@ var neListSort = []string{
"N3IWF",
"NEF",
"LMF",
"MOCNGW",
}
// 实例化数据层 NeInfoImpl 结构体

View File

@@ -0,0 +1,27 @@
package repository
import "be.ems/src/modules/network_element/model"
// INeLicense 网元授权激活信息 数据层接口
type INeLicense interface {
// SelectPage 根据条件分页查询字典类型
SelectPage(query map[string]any) map[string]any
// SelectList 根据实体查询
SelectList(neLicense model.NeLicense) []model.NeLicense
// SelectByIds 通过ID查询
SelectByIds(ids []string) []model.NeLicense
// Insert 新增信息
Insert(neLicense model.NeLicense) string
// Update 修改信息
Update(neLicense model.NeLicense) int64
// DeleteByIds 批量删除信息
DeleteByIds(ids []string) int64
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
CheckUniqueTypeAndID(neLicense model.NeLicense) string
}

View File

@@ -0,0 +1,333 @@
package repository
import (
"fmt"
"strings"
"time"
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/repo"
"be.ems/src/modules/network_element/model"
)
// 实例化数据层 NewNeLicense 结构体
var NewNeLicenseImpl = &NeLicenseImpl{
selectSql: `select
id, ne_type, ne_id, activation_request_code, license_path, serial_num, expiry_date, status, remark, create_by, create_time, update_by, update_time
from ne_license`,
resultMap: map[string]string{
"id": "ID",
"ne_type": "NeType",
"ne_id": "NeId",
"activation_request_code": "ActivationRequestCode",
"license_path": "LicensePath",
"serial_num": "SerialNum",
"expiry_date": "ExpiryDate",
"status": "Status",
"remark": "Remark",
"create_by": "CreateBy",
"create_time": "CreateTime",
"update_by": "UpdateBy",
"update_time": "UpdateTime",
},
}
// NeLicenseImpl 网元授权激活信息 数据层处理
type NeLicenseImpl struct {
// 查询视图对象SQL
selectSql string
// 结果字段与实体映射
resultMap map[string]string
}
// convertResultRows 将结果记录转实体结果组
func (r *NeLicenseImpl) convertResultRows(rows []map[string]any) []model.NeLicense {
arr := make([]model.NeLicense, 0)
for _, row := range rows {
item := model.NeLicense{}
for key, value := range row {
if keyMapper, ok := r.resultMap[key]; ok {
repo.SetFieldValue(&item, keyMapper, value)
}
}
arr = append(arr, item)
}
return arr
}
// SelectPage 根据条件分页查询字典类型
func (r *NeLicenseImpl) SelectPage(query map[string]any) map[string]any {
// 查询条件拼接
var conditions []string
var params []any
if v, ok := query["neType"]; ok && v != "" {
conditions = append(conditions, "ne_type = ?")
params = append(params, strings.Trim(v.(string), " "))
}
if v, ok := query["neId"]; ok && v != "" {
conditions = append(conditions, "ne_id = ?")
params = append(params, strings.Trim(v.(string), " "))
}
if v, ok := query["expiryDate"]; ok && v != "" {
conditions = append(conditions, "expiry_date = ?")
params = append(params, strings.Trim(v.(string), " "))
}
if v, ok := query["createBy"]; ok && v != "" {
conditions = append(conditions, "create_by like concat(?, '%')")
params = append(params, strings.Trim(v.(string), " "))
}
// 构建查询条件语句
whereSql := ""
if len(conditions) > 0 {
whereSql += " where " + strings.Join(conditions, " and ")
}
result := map[string]any{
"total": 0,
"rows": []model.NeHost{},
}
// 查询数量 长度为0直接返回
totalSql := "select count(1) as 'total' from ne_license"
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
if err != nil {
logger.Errorf("total err => %v", err)
return result
}
total := parse.Number(totalRows[0]["total"])
if total == 0 {
return result
} else {
result["total"] = total
}
// 分页
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
pageSql := " limit ?,? "
params = append(params, pageNum*pageSize)
params = append(params, pageSize)
// 查询数据
querySql := r.selectSql + whereSql + pageSql
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)
return result
}
// 转换实体
result["rows"] = r.convertResultRows(results)
return result
}
// SelectList 根据实体查询
func (r *NeLicenseImpl) SelectList(neLicense model.NeLicense) []model.NeLicense {
// 查询条件拼接
var conditions []string
var params []any
if neLicense.NeType != "" {
conditions = append(conditions, "ne_type = ?")
params = append(params, neLicense.NeType)
}
if neLicense.NeId != "" {
conditions = append(conditions, "ne_id = ?")
params = append(params, neLicense.NeId)
}
if neLicense.ExpiryDate != "" {
conditions = append(conditions, "expiry_date = ?")
params = append(params, neLicense.ExpiryDate)
}
if neLicense.CreateBy != "" {
conditions = append(conditions, "create_by like concat(?, '%')")
params = append(params, neLicense.CreateBy)
}
// 构建查询条件语句
whereSql := ""
if len(conditions) > 0 {
whereSql += " where " + strings.Join(conditions, " and ")
}
// 查询数据
querySql := r.selectSql + whereSql + " order by id asc "
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)
}
// 转换实体
return r.convertResultRows(results)
}
// SelectByIds 通过ID查询
func (r *NeLicenseImpl) SelectByIds(cmdIds []string) []model.NeLicense {
placeholder := repo.KeyPlaceholderByQuery(len(cmdIds))
querySql := r.selectSql + " where id in (" + placeholder + ")"
parameters := repo.ConvertIdsSlice(cmdIds)
results, err := datasource.RawDB("", querySql, parameters)
if err != nil {
logger.Errorf("query err => %v", err)
return []model.NeLicense{}
}
// 转换实体
return r.convertResultRows(results)
}
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
func (r *NeLicenseImpl) CheckUniqueTypeAndID(neLicense model.NeLicense) string {
// 查询条件拼接
var conditions []string
var params []any
if neLicense.NeType != "" {
conditions = append(conditions, "ne_type = ?")
params = append(params, neLicense.NeType)
}
if neLicense.NeId != "" {
conditions = append(conditions, "ne_id = ?")
params = append(params, neLicense.NeId)
}
// 构建查询条件语句
whereSql := ""
if len(conditions) > 0 {
whereSql += " where " + strings.Join(conditions, " and ")
} else {
return ""
}
// 查询数据
querySql := "select id as 'str' from ne_license " + whereSql + " limit 1"
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err %v", err)
return ""
}
if len(results) > 0 {
return fmt.Sprint(results[0]["str"])
}
return ""
}
// Insert 新增信息
func (r *NeLicenseImpl) Insert(neLicense model.NeLicense) string {
// 参数拼接
params := make(map[string]any)
if neLicense.NeType != "" {
params["ne_type"] = neLicense.NeType
}
if neLicense.NeId != "" {
params["ne_id"] = neLicense.NeId
}
if neLicense.ActivationRequestCode != "" {
params["activation_request_code"] = neLicense.ActivationRequestCode
}
if neLicense.LicensePath != "" {
params["license_path"] = neLicense.LicensePath
}
if neLicense.SerialNum != "" {
params["serial_num"] = neLicense.SerialNum
}
if neLicense.ExpiryDate != "" {
params["expiry_date"] = neLicense.ExpiryDate
}
if neLicense.Status != "" {
params["status"] = neLicense.Status
}
if neLicense.Remark != "" {
params["remark"] = neLicense.Remark
}
if neLicense.CreateBy != "" {
params["create_by"] = neLicense.CreateBy
params["create_time"] = time.Now().UnixMilli()
}
// 构建执行语句
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
sql := "insert into ne_license (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
db := datasource.DefaultDB()
// 开启事务
tx := db.Begin()
// 执行插入
err := tx.Exec(sql, values...).Error
if err != nil {
logger.Errorf("insert row : %v", err.Error())
tx.Rollback()
return ""
}
// 获取生成的自增 ID
var insertedID string
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
if err != nil {
logger.Errorf("insert last id : %v", err.Error())
tx.Rollback()
return ""
}
// 提交事务
tx.Commit()
return insertedID
}
// Update 修改信息
func (r *NeLicenseImpl) Update(neLicense model.NeLicense) int64 {
// 参数拼接
params := make(map[string]any)
if neLicense.NeType != "" {
params["ne_type"] = neLicense.NeType
}
if neLicense.NeId != "" {
params["ne_id"] = neLicense.NeId
}
if neLicense.ActivationRequestCode != "" {
params["activation_request_code"] = neLicense.ActivationRequestCode
}
if neLicense.LicensePath != "" {
params["license_path"] = neLicense.LicensePath
}
if neLicense.SerialNum != "" {
params["serial_num"] = neLicense.SerialNum
}
if neLicense.ExpiryDate != "" {
params["expiry_date"] = neLicense.ExpiryDate
}
if neLicense.Status != "" {
params["status"] = neLicense.Status
}
if neLicense.Remark != "" {
params["remark"] = neLicense.Remark
}
if neLicense.UpdateBy != "" {
params["update_by"] = neLicense.UpdateBy
params["update_time"] = time.Now().UnixMilli()
}
// 构建执行语句
keys, values := repo.KeyValueByUpdate(params)
sql := "update ne_license set " + strings.Join(keys, ",") + " where id = ?"
// 执行更新
values = append(values, neLicense.ID)
rows, err := datasource.ExecDB("", sql, values)
if err != nil {
logger.Errorf("update row : %v", err.Error())
return 0
}
return rows
}
// DeleteByIds 批量删除信息
func (r *NeLicenseImpl) DeleteByIds(cmdIds []string) int64 {
placeholder := repo.KeyPlaceholderByQuery(len(cmdIds))
sql := "delete from ne_license where id in (" + placeholder + ")"
parameters := repo.ConvertIdsSlice(cmdIds)
results, err := datasource.ExecDB("", sql, parameters)
if err != nil {
logger.Errorf("delete err => %v", err)
return 0
}
return results
}

View File

@@ -22,6 +22,6 @@ type INeSoftware interface {
// DeleteByIds 批量删除信息
DeleteByIds(ids []string) int64
// CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一
CheckUniqueTypeAndFileNameAndVersion(neSoftware model.NeSoftware) string
// CheckUniqueTypeAndNameAndVersion 校验网元类型和文件名版本是否唯一
CheckUniqueTypeAndNameAndVersion(neSoftware model.NeSoftware) string
}

View File

@@ -15,18 +15,19 @@ import (
// 实例化数据层 NewNeSoftware 结构体
var NewNeSoftwareImpl = &NeSoftwareImpl{
selectSql: `select
id, ne_type, file_name, path, version, md5_sum, status, comment, update_time
id, ne_type, name, path, version, description, create_by, create_time, update_by, update_time
from ne_software`,
resultMap: map[string]string{
"id": "ID",
"ne_type": "NeType",
"file_name": "FileName",
"name": "Name",
"path": "Path",
"version": "Version",
"md5_sum": "Md5Sum",
"status": "Status",
"comment": "Comment",
"description": "Description",
"create_by": "CreateBy",
"create_time": "CreateTime",
"update_by": "UpdateBy",
"update_time": "UpdateTime",
},
}
@@ -63,8 +64,8 @@ func (r *NeSoftwareImpl) SelectPage(query map[string]any) map[string]any {
conditions = append(conditions, "ne_type = ?")
params = append(params, strings.Trim(v.(string), " "))
}
if v, ok := query["fileName"]; ok && v != "" {
conditions = append(conditions, "file_name like concat(?, '%')")
if v, ok := query["name"]; ok && v != "" {
conditions = append(conditions, "name like concat(?, '%')")
params = append(params, strings.Trim(v.(string), " "))
}
if v, ok := query["version"]; ok && v != "" {
@@ -133,9 +134,9 @@ func (r *NeSoftwareImpl) SelectList(neSoftware model.NeSoftware) []model.NeSoftw
conditions = append(conditions, "version = ?")
params = append(params, neSoftware.Version)
}
if neSoftware.FileName != "" {
conditions = append(conditions, "file_name like concat(?, '%')")
params = append(params, neSoftware.FileName)
if neSoftware.Name != "" {
conditions = append(conditions, "name like concat(?, '%')")
params = append(params, neSoftware.Name)
}
// 构建查询条件语句
@@ -169,8 +170,8 @@ func (r *NeSoftwareImpl) SelectByIds(cmdIds []string) []model.NeSoftware {
return r.convertResultRows(results)
}
// CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一
func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neSoftware model.NeSoftware) string {
// CheckUniqueTypeAndNameAndVersion 校验网元类型和文件名版本是否唯一
func (r *NeSoftwareImpl) CheckUniqueTypeAndNameAndVersion(neSoftware model.NeSoftware) string {
// 查询条件拼接
var conditions []string
var params []any
@@ -182,9 +183,9 @@ func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neSoftware model.N
conditions = append(conditions, "version = ?")
params = append(params, neSoftware.Version)
}
if neSoftware.FileName != "" {
conditions = append(conditions, "file_name = ?")
params = append(params, neSoftware.FileName)
if neSoftware.Name != "" {
conditions = append(conditions, "name = ?")
params = append(params, neSoftware.Name)
}
// 构建查询条件语句
@@ -215,8 +216,8 @@ func (r *NeSoftwareImpl) Insert(neSoftware model.NeSoftware) string {
if neSoftware.NeType != "" {
params["ne_type"] = neSoftware.NeType
}
if neSoftware.FileName != "" {
params["file_name"] = neSoftware.FileName
if neSoftware.Name != "" {
params["name"] = neSoftware.Name
}
if neSoftware.Path != "" {
params["path"] = neSoftware.Path
@@ -224,19 +225,11 @@ func (r *NeSoftwareImpl) Insert(neSoftware model.NeSoftware) string {
if neSoftware.Version != "" {
params["version"] = neSoftware.Version
}
if neSoftware.Md5Sum != "" {
params["md5_sum"] = neSoftware.Md5Sum
params["description"] = neSoftware.Description
if neSoftware.CreateBy != "" {
params["create_by"] = neSoftware.CreateBy
params["create_time"] = time.Now().UnixMilli()
}
if neSoftware.Status != "" {
params["status"] = neSoftware.Status
}
if neSoftware.Comment != "" {
params["comment"] = neSoftware.Comment
}
if neSoftware.Status != "" {
params["status"] = neSoftware.Status
}
params["update_time"] = time.Now()
// 构建执行语句
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
@@ -272,8 +265,8 @@ func (r *NeSoftwareImpl) Update(neSoftware model.NeSoftware) int64 {
if neSoftware.NeType != "" {
params["ne_type"] = neSoftware.NeType
}
if neSoftware.FileName != "" {
params["file_name"] = neSoftware.FileName
if neSoftware.Name != "" {
params["name"] = neSoftware.Name
}
if neSoftware.Path != "" {
params["path"] = neSoftware.Path
@@ -281,19 +274,11 @@ func (r *NeSoftwareImpl) Update(neSoftware model.NeSoftware) int64 {
if neSoftware.Version != "" {
params["version"] = neSoftware.Version
}
if neSoftware.Md5Sum != "" {
params["md5_sum"] = neSoftware.Md5Sum
params["description"] = neSoftware.Description
if neSoftware.UpdateBy != "" {
params["update_by"] = neSoftware.UpdateBy
params["update_time"] = time.Now().UnixMilli()
}
if neSoftware.Status != "" {
params["status"] = neSoftware.Status
}
if neSoftware.Comment != "" {
params["comment"] = neSoftware.Comment
}
if neSoftware.Status != "" {
params["status"] = neSoftware.Status
}
params["update_time"] = time.Now()
// 构建执行语句
keys, values := repo.KeyValueByUpdate(params)

View File

@@ -15,7 +15,7 @@ import (
// 实例化数据层 NewNeVersion 结构体
var NewNeVersionImpl = &NeVersionImpl{
selectSql: `select
id, ne_type, ne_id, version, file_path, pre_version, pre_file, new_version, new_file, status, update_time
id, ne_type, ne_id, version, path, pre_version, pre_path, new_version, new_path, status, create_by, create_time, update_by, update_time
from ne_version`,
resultMap: map[string]string{
@@ -23,12 +23,15 @@ var NewNeVersionImpl = &NeVersionImpl{
"ne_type": "NeType",
"ne_id": "NeId",
"version": "Version",
"file_path": "FilePath",
"path": "Path",
"pre_version": "PreVersion",
"pre_file": "PreFile",
"pre_path": "PrePath",
"new_version": "NewVersion",
"new_file": "NewFile",
"new_path": "NewPath",
"status": "Status",
"create_by": "CreateBy",
"create_time": "CreateTime",
"update_by": "UpdateBy",
"update_time": "UpdateTime",
},
}
@@ -139,9 +142,9 @@ func (r *NeVersionImpl) SelectList(neVersion model.NeVersion) []model.NeVersion
conditions = append(conditions, "version like concat(?, '%')")
params = append(params, neVersion.Version)
}
if neVersion.FilePath != "" {
conditions = append(conditions, "file_path like concat(?, '%')")
params = append(params, neVersion.FilePath)
if neVersion.Path != "" {
conditions = append(conditions, "path like concat(?, '%')")
params = append(params, neVersion.Path)
}
// 构建查询条件语句
@@ -151,7 +154,7 @@ func (r *NeVersionImpl) SelectList(neVersion model.NeVersion) []model.NeVersion
}
// 查询数据
querySql := r.selectSql + whereSql + " order by update_time asc "
querySql := r.selectSql + whereSql + " order by id asc "
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)
@@ -223,25 +226,28 @@ func (r *NeVersionImpl) Insert(neVersion model.NeVersion) string {
if neVersion.Version != "" {
params["version"] = neVersion.Version
}
if neVersion.FilePath != "" {
params["file_path"] = neVersion.FilePath
if neVersion.Path != "" {
params["path"] = neVersion.Path
}
if neVersion.PreVersion != "" {
params["pre_version"] = neVersion.PreVersion
}
if neVersion.PreFile != "" {
params["pre_file"] = neVersion.PreFile
if neVersion.PrePath != "" {
params["pre_path"] = neVersion.PrePath
}
if neVersion.NewVersion != "" {
params["new_version"] = neVersion.NewVersion
}
if neVersion.NewFile != "" {
params["new_file"] = neVersion.NewFile
if neVersion.NewPath != "" {
params["new_path"] = neVersion.NewPath
}
if neVersion.Status != "" {
params["status"] = neVersion.Status
}
params["update_time"] = time.Now()
if neVersion.CreateBy != "" {
params["create_by"] = neVersion.CreateBy
params["create_time"] = time.Now().UnixMilli()
}
// 构建执行语句
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
@@ -283,25 +289,28 @@ func (r *NeVersionImpl) Update(neVersion model.NeVersion) int64 {
if neVersion.Version != "" {
params["version"] = neVersion.Version
}
if neVersion.FilePath != "" {
params["file_path"] = neVersion.FilePath
if neVersion.Path != "" {
params["path"] = neVersion.Path
}
if neVersion.PreVersion != "" {
params["pre_version"] = neVersion.PreVersion
}
if neVersion.PreFile != "" {
params["pre_file"] = neVersion.PreFile
if neVersion.PrePath != "" {
params["pre_path"] = neVersion.PrePath
}
if neVersion.NewVersion != "" {
params["new_version"] = neVersion.NewVersion
}
if neVersion.NewFile != "" {
params["new_file"] = neVersion.NewFile
if neVersion.NewPath != "" {
params["new_path"] = neVersion.NewPath
}
if neVersion.Status != "" {
params["status"] = neVersion.Status
}
params["update_time"] = time.Now()
if neVersion.UpdateBy != "" {
params["update_by"] = neVersion.UpdateBy
params["update_time"] = time.Now().UnixMilli()
}
// 构建执行语句
keys, values := repo.KeyValueByUpdate(params)

View File

@@ -69,6 +69,11 @@ func NeConfigOMC(neInfo model.NeInfo) (map[string]any, error) {
return nil, err
}
// 200 成功无数据时
if len(resBytes) == 0 {
return resData, nil
}
// 序列化结果
err = json.Unmarshal(resBytes, &resData)
if err != nil {

View File

@@ -42,4 +42,13 @@ type INeInfo interface {
// CheckUniqueNeTypeAndNeId 校验同类型下标识是否唯一
CheckUniqueNeTypeAndNeId(neType, neId, infoId string) bool
// NeRunCMD 向网元发送cmd命令
NeRunCMD(neType, neId, cmd string) (string, error)
// NeConfigFileRead 网元配置文件读取 网元配置yaml文件复制到本地后通过filePath读取
NeConfigFileRead(neInfo model.NeInfo, filePath string) []string
// NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端
NeConfigFileWirte(neInfo model.NeInfo, filePath, content string, sync bool) error
}

View File

@@ -3,10 +3,14 @@ package service
import (
"encoding/json"
"fmt"
"os"
"runtime"
"strings"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/logger"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/ssh"
"be.ems/src/modules/network_element/model"
"be.ems/src/modules/network_element/repository"
)
@@ -28,7 +32,7 @@ type NeInfoImpl struct {
// SelectNeInfoByNeTypeAndNeID 通过ne_type和ne_id查询网元信息
func (r *NeInfoImpl) SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeInfo {
var neInfo model.NeInfo
key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, neType, neID)
key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, strings.ToUpper(neType), neID)
jsonStr, _ := redis.Get("", key)
if len(jsonStr) > 7 {
err := json.Unmarshal([]byte(jsonStr), &neInfo)
@@ -37,7 +41,7 @@ func (r *NeInfoImpl) SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeIn
}
} else {
neInfo = r.neInfoRepository.SelectNeInfoByNeTypeAndNeID(neType, neID)
if neInfo.NeId == neID {
if neInfo.ID != "" && neInfo.NeId == neID {
redis.Del("", key)
values, _ := json.Marshal(neInfo)
redis.Set("", key, string(values))
@@ -49,10 +53,10 @@ func (r *NeInfoImpl) SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeIn
// RefreshByNeTypeAndNeID 通过ne_type和ne_id刷新redis中的缓存
func (r *NeInfoImpl) RefreshByNeTypeAndNeID(neType, neID string) model.NeInfo {
var neInfo model.NeInfo
key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, neType, neID)
key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, strings.ToUpper(neType), neID)
redis.Del("", key)
neInfo = r.neInfoRepository.SelectNeInfoByNeTypeAndNeID(neType, neID)
if neInfo.NeId == neID {
if neInfo.ID != "" && neInfo.NeId == neID {
values, _ := json.Marshal(neInfo)
redis.Set("", key, string(values))
}
@@ -92,7 +96,7 @@ func (r *NeInfoImpl) SelectNeInfoByRmuid(rmUid string) model.NeInfo {
} else {
neInfos := r.SelectList(neInfo, false)
for _, v := range neInfos {
key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, v.NeType, v.NeId)
key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, strings.ToUpper(v.NeType), v.NeId)
redis.Del("", key)
values, _ := json.Marshal(v)
redis.Set("", key, string(values))
@@ -124,6 +128,7 @@ func (r *NeInfoImpl) SelectPage(query map[string]any, bandStatus bool) map[strin
// 网元状态设置为离线
if v.Status != "1" {
v.Status = "1"
(*arr)[i].Status = v.Status
r.neInfoRepository.Update(v)
}
continue
@@ -139,6 +144,7 @@ func (r *NeInfoImpl) SelectPage(query map[string]any, bandStatus bool) map[strin
} else {
v.Status = "0"
}
(*arr)[i].Status = v.Status
r.neInfoRepository.Update(v)
}
}
@@ -166,6 +172,7 @@ func (r *NeInfoImpl) SelectList(ne model.NeInfo, bandStatus bool) []model.NeInfo
// 网元状态设置为离线
if v.Status != "1" {
v.Status = "1"
(*neList)[i].Status = v.Status
r.neInfoRepository.Update(v)
}
continue
@@ -181,6 +188,7 @@ func (r *NeInfoImpl) SelectList(ne model.NeInfo, bandStatus bool) []model.NeInfo
} else {
v.Status = "0"
}
(*neList)[i].Status = v.Status
r.neInfoRepository.Update(v)
}
}
@@ -290,3 +298,139 @@ func (r *NeInfoImpl) CheckUniqueNeTypeAndNeId(neType, neId, infoId string) bool
}
return uniqueId == ""
}
// NeRunCMD 向网元发送cmd命令
func (r *NeInfoImpl) NeRunCMD(neType, neId, cmd string) (string, error) {
neInfo := r.SelectNeInfoByNeTypeAndNeID(neType, neId)
if neInfo.NeId != neId {
logger.Errorf("NeRunCMD NeType:%s NeID:%s not found", neType, neId)
return "", fmt.Errorf("neinfo not found")
}
// 带主机信息
if neInfo.HostIDs != "" {
neInfo.Hosts = r.neHostRepository.SelectByIds(strings.Split(neInfo.HostIDs, ","))
if len(neInfo.Hosts) <= 0 {
logger.Errorf("NeRunCMD Hosts %s not found", neInfo.HostIDs)
return "", fmt.Errorf("neinfo host not found")
}
}
neHost := neInfo.Hosts[0]
if neHost.HostType != "ssh" {
logger.Errorf("NeRunCMD Hosts first HostType %s not ssh", neHost.HostType)
return "", fmt.Errorf("neinfo host type not ssh")
}
var connSSH ssh.ConnSSH
neHost.CopyTo(&connSSH)
client, err := connSSH.NewClient()
if err != nil {
logger.Errorf("NeRunCMD NewClient err => %s", err.Error())
return "", fmt.Errorf("neinfo ssh client new err")
}
defer client.Close()
// 执行命令
output, err := client.RunCMD(cmd)
if err != nil {
logger.Errorf("NeRunCMD RunCMD %s err => %s", output, err.Error())
return "", fmt.Errorf("neinfo ssh run cmd err")
}
return output, nil
}
// NeConfigFileRead 网元配置文件读取 网元配置yaml文件复制到本地后通过filePath读取
func (r *NeInfoImpl) NeConfigFileRead(neInfo model.NeInfo, filePath string) []string {
files := []string{}
neTypeLower := strings.ToLower(neInfo.NeType)
// 网管本地路径
omcPath := "/usr/local/etc/omc/ne_config"
if runtime.GOOS == "windows" {
omcPath = fmt.Sprintf("C:%s", omcPath)
}
omcPath = fmt.Sprintf("%s/%s/%s", omcPath, neTypeLower, neInfo.NeId)
// 读取文件内容
if filePath != "" {
bytes, err := os.ReadFile(fmt.Sprintf("%s/%s", omcPath, filePath))
if err != nil {
logger.Warnf("NeConfigFile ReadFile => %s", err.Error())
return files
}
files = append(files, string(bytes))
return files
}
// 删除原有配置文件
// err := os.RemoveAll(omcPath)
// if err != nil {
// logger.Warnf("NeConfigFile Remove => %s", err.Error())
// return files
// }
// 网元端配置路径
nePath := "/usr/local/etc"
nePath = fmt.Sprintf("%s/%s", nePath, neTypeLower)
// 各个网元与网元间约定配置文件
err := ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/oam_manager.yaml", omcPath+"/oam_manager.yaml")
if err == nil {
files = append(files, "oam_manager.yaml")
}
// 根据情况复制网元特殊配置
switch neTypeLower {
case "ausf":
err = ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/ausfcfg.yaml", omcPath+"/ausfcfg.yaml")
if err == nil {
files = append(files, "ausfcfg.yaml")
}
case "smf":
ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/smf_conf.yaml", omcPath+"/smf_conf.yaml")
if err == nil {
files = append(files, "smf_conf.yaml")
}
ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/smf_policy.yaml", omcPath+"/smf_policy.yaml")
if err == nil {
files = append(files, "smf_policy.yaml")
}
case "ims":
}
return files
}
// NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端
func (r *NeInfoImpl) NeConfigFileWirte(neInfo model.NeInfo, filePath, content string, sync bool) error {
neTypeLower := strings.ToLower(neInfo.NeType)
// 网管本地路径
omcPath := "/usr/local/etc/omc/ne_config"
if runtime.GOOS == "windows" {
omcPath = fmt.Sprintf("C:%s", omcPath)
}
localFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neInfo.NeId, filePath)
err := os.WriteFile(localFilePath, []byte(content), 0644)
if err != nil {
logger.Warnf("NeConfigFile WriteFile => %s", err.Error())
return fmt.Errorf("please check if the file exists or write permissions")
}
// 同步到网元端
if sync {
// 网元端配置路径
neFilePath := fmt.Sprintf("/usr/local/etc/%s/%s", neTypeLower, filePath)
// 修改网元文件权限
r.NeRunCMD(neInfo.NeType, neInfo.NeId, fmt.Sprintf("sudo chmod o+w %s", neFilePath))
// 复制到网元进行覆盖
err = ssh.FileSCPLocalToNe(neInfo.IP, localFilePath, neFilePath)
if err != nil {
logger.Warnf("NeConfigFile SyncFile => %s", err.Error())
return fmt.Errorf("please check if scp remote copy is allowed")
}
}
return nil
}

View File

@@ -0,0 +1,37 @@
package service
import "be.ems/src/modules/network_element/model"
// INeLicense 网元授权激活信息 服务层接口
type INeLicense interface {
// SelectPage 根据条件分页查询字典类型
SelectPage(query map[string]any) map[string]any
// SelectList 根据实体查询
SelectList(neLicense model.NeLicense) []model.NeLicense
// SelectById 通过ID查询
SelectById(id string) model.NeLicense
// Insert 新增信息
Insert(neLicense model.NeLicense) string
// Update 修改信息
Update(neLicense model.NeLicense) int64
// DeleteByIds 批量删除信息
DeleteByIds(ids []string) (int64, error)
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
CheckUniqueTypeAndID(neType, neId, id string) bool
// SelectByNeTypeAndNeID 通过ne_type和ne_id查询信息
SelectByNeTypeAndNeID(neType, neId string) model.NeLicense
// ReadLicenseInfo 读取授权文件信息
// 激活申请码, 激活文件
ReadLicenseInfo(neInfo model.NeInfo) (string, string)
// UploadToNeHost 授权文件上传到网元主机
UploadToNeHost(neLicense model.NeLicense) error
}

View File

@@ -0,0 +1,183 @@
package service
import (
"fmt"
"os"
"runtime"
"strings"
"time"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/ssh"
"be.ems/src/modules/network_element/model"
"be.ems/src/modules/network_element/repository"
)
// 实例化服务层 NeLicenseImpl 结构体
var NewNeLicenseImpl = &NeLicenseImpl{
neLicenseRepository: repository.NewNeLicenseImpl,
}
// NeLicenseImpl 网元授权激活信息 服务层处理
type NeLicenseImpl struct {
// 网元授权激活信息表
neLicenseRepository repository.INeLicense
}
// SelectNeHostPage 分页查询列表数据
func (r *NeLicenseImpl) SelectPage(query map[string]any) map[string]any {
return r.neLicenseRepository.SelectPage(query)
}
// SelectConfigList 查询列表
func (r *NeLicenseImpl) SelectList(neLicense model.NeLicense) []model.NeLicense {
return r.neLicenseRepository.SelectList(neLicense)
}
// SelectByIds 通过ID查询
func (r *NeLicenseImpl) SelectById(id string) model.NeLicense {
if id == "" {
return model.NeLicense{}
}
neLicenses := r.neLicenseRepository.SelectByIds([]string{id})
if len(neLicenses) > 0 {
return neLicenses[0]
}
return model.NeLicense{}
}
// Insert 新增信息
func (r *NeLicenseImpl) Insert(neLicense model.NeLicense) string {
return r.neLicenseRepository.Insert(neLicense)
}
// Update 修改信息
func (r *NeLicenseImpl) Update(neLicense model.NeLicense) int64 {
return r.neLicenseRepository.Update(neLicense)
}
// DeleteByIds 批量删除信息
func (r *NeLicenseImpl) DeleteByIds(ids []string) (int64, error) {
// 检查是否存在
rowIds := r.neLicenseRepository.SelectByIds(ids)
if len(rowIds) <= 0 {
return 0, fmt.Errorf("neLicense.noData")
}
if len(rowIds) == len(ids) {
rows := r.neLicenseRepository.DeleteByIds(ids)
return rows, nil
}
// 删除信息失败!
return 0, fmt.Errorf("delete fail")
}
// SelectByTypeAndID 通过网元类型和网元ID查询
func (r *NeLicenseImpl) SelectByTypeAndID(neType, neId string) model.NeLicense {
neLicenses := r.neLicenseRepository.SelectList(model.NeLicense{
NeType: neType,
NeId: neId,
})
if len(neLicenses) > 0 {
return neLicenses[0]
}
return model.NeLicense{}
}
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
func (r *NeLicenseImpl) CheckUniqueTypeAndID(neType, neId, id string) bool {
uniqueId := r.neLicenseRepository.CheckUniqueTypeAndID(model.NeLicense{
NeType: neType,
NeId: neId,
})
if uniqueId == id {
return true
}
return uniqueId == ""
}
// SelectByNeTypeAndNeID 通过ne_type和ne_id查询信息
func (r *NeLicenseImpl) SelectByNeTypeAndNeID(neType, neId string) model.NeLicense {
neLicenses := r.neLicenseRepository.SelectList(model.NeLicense{
NeType: neType,
NeId: neId,
})
if len(neLicenses) > 0 {
return neLicenses[0]
}
return model.NeLicense{}
}
// ReadLicenseInfo 读取授权文件信息
// 激活申请码, 激活文件
func (r *NeLicenseImpl) ReadLicenseInfo(neInfo model.NeInfo) (string, string) {
neTypeLower := strings.ToLower(neInfo.NeType)
// 网管本地路径
omcPath := "/usr/local/etc/omc/ne_license"
if runtime.GOOS == "windows" {
omcPath = fmt.Sprintf("C:%s", omcPath)
}
omcPath = fmt.Sprintf("%s/%s/%s", omcPath, neTypeLower, neInfo.NeId)
// 网元端授权文件路径
nePath := fmt.Sprintf("/usr/local/etc/%s/license", neTypeLower)
// 复制授权申请码到本地
err := ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/Activation_request_code.txt", omcPath+"/Activation_request_code.txt")
if err != nil {
return "", ""
}
// 读取文件内容
bytes, err := os.ReadFile(omcPath + "/Activation_request_code.txt")
if err != nil {
return "", ""
}
// 激活文件
licensePath := ""
if err = ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/system.ini", omcPath+"/system.ini"); err == nil {
licensePath = omcPath + "/system.ini"
}
return strings.TrimSpace(string(bytes)), licensePath
}
// UploadToNeHost 授权文件上传到网元主机
func (r *NeLicenseImpl) UploadToNeHost(neLicense model.NeLicense) error {
// 检查文件是否存在
omcLicensePath := file.ParseUploadFilePath(neLicense.LicensePath)
if _, err := os.Stat(omcLicensePath); err != nil {
return fmt.Errorf("file read failure")
}
// 检查网元主机
neHostInfo := NewNeHostImpl.SelectById(neLicense.HostId)
if neHostInfo.HostType != "ssh" || neHostInfo.HostID != neLicense.HostId {
return fmt.Errorf("no found host info")
}
// 网元端授权文件路径
neTypeLower := strings.ToLower(neLicense.NeType)
neLicensePath := fmt.Sprintf("/usr/local/etc/%s/license", neTypeLower)
// 修改文件夹权限
NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, fmt.Sprintf("sudo chmod o+w %s/", neLicensePath))
// 尝试备份授权文件
neLicensePathBack := fmt.Sprintf("%s/system_%s.ini", neLicensePath, time.Now().Format("20060102_150405"))
NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, fmt.Sprintf("sudo cp -rf %s/system.ini %s", neLicensePath, neLicensePathBack))
// 上传授权文件去覆盖
NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, fmt.Sprintf("sudo chmod o+w %s/system.ini", neLicensePath))
if err := ssh.FileSCPLocalToNe(neHostInfo.Addr, omcLicensePath, neLicensePath+"/system.ini"); err != nil {
return fmt.Errorf("error uploading license")
}
// 重启服务
if neLicense.Reload {
cmdStr := fmt.Sprintf("sudo service %s restart", neTypeLower)
if neTypeLower == "ims" {
cmdStr = "sudo ims-stop && sudo ims-start"
} else if neTypeLower == "omc" {
cmdStr = "sudo /usr/local/omc/bin/omcsvc.sh restart"
}
NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, cmdStr)
}
return nil
}

View File

@@ -22,12 +22,10 @@ type INeSoftware interface {
// DeleteByIds 批量删除信息
DeleteByIds(ids []string) (int64, error)
// SelectByVersionAndPath 通过文件版本和路径查询
SelectByVersionAndPath(version, path string) model.NeSoftware
// CheckUniqueTypeAndNameAndVersion 校验网元类型和文件版本是否唯一
CheckUniqueTypeAndNameAndVersion(neType, name, version, id string) bool
// CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一
CheckUniqueTypeAndFileNameAndVersion(neType, fileName, version, id string) bool
// Install 安装软件包
Install(neSoftware model.NeSoftware) (string, error)
// UploadToNeHost 安装包上传到网元主机
// 返回执行命令步骤
UploadToNeHost(neSoftware model.NeSoftware) ([]string, error)
}

View File

@@ -2,7 +2,12 @@ package service
import (
"fmt"
"os"
"path/filepath"
"strings"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/ssh"
"be.ems/src/modules/network_element/model"
"be.ems/src/modules/network_element/repository"
)
@@ -66,24 +71,12 @@ func (r *NeSoftwareImpl) DeleteByIds(ids []string) (int64, error) {
return 0, fmt.Errorf("delete fail")
}
// SelectByVersionAndPath 通过文件版本和路径查询
func (r *NeSoftwareImpl) SelectByVersionAndPath(version, path string) model.NeSoftware {
neSoftwares := r.neSoftwareRepository.SelectList(model.NeSoftware{
// CheckUniqueTypeAndNameAndVersion 校验网元类型和文件版本是否唯一
func (r *NeSoftwareImpl) CheckUniqueTypeAndNameAndVersion(neType, name, version, id string) bool {
uniqueId := r.neSoftwareRepository.CheckUniqueTypeAndNameAndVersion(model.NeSoftware{
NeType: neType,
Name: name,
Version: version,
Path: path,
})
if len(neSoftwares) > 0 {
return neSoftwares[0]
}
return model.NeSoftware{}
}
// CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一
func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neType, fileName, version, id string) bool {
uniqueId := r.neSoftwareRepository.CheckUniqueTypeAndFileNameAndVersion(model.NeSoftware{
NeType: neType,
FileName: fileName,
Version: version,
})
if uniqueId == id {
return true
@@ -91,7 +84,54 @@ func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neType, fileName,
return uniqueId == ""
}
// Install 安装软件包
func (r *NeSoftwareImpl) Install(neSoftware model.NeSoftware) (string, error) {
return "", nil
// UploadToNeHost 安装包上传到网元主机
// 返回执行命令步骤
func (r *NeSoftwareImpl) UploadToNeHost(neSoftware model.NeSoftware) ([]string, error) {
cmdStrArr := []string{}
// 检查文件是否存在
filePath := file.ParseUploadFilePath(neSoftware.Path)
if _, err := os.Stat(filePath); err != nil {
return cmdStrArr, fmt.Errorf("file read failure")
}
fileName := filepath.Base(neSoftware.Path)
if strings.Contains(fileName, "*") {
fileName = strings.ReplaceAll(fileName, "*", "_")
}
nePath := "/tmp"
neFilePath := fmt.Sprintf("%s/%s", nePath, fileName)
// 检查网元主机
neHostInfo := NewNeHostImpl.SelectById(neSoftware.HostId)
if neHostInfo.HostType != "ssh" || neHostInfo.HostID != neSoftware.HostId {
return cmdStrArr, fmt.Errorf("no found host info")
}
// 上传软件包到 /tmp
if err := ssh.FileSCPLocalToNe(neHostInfo.Addr, filePath, neFilePath); err != nil {
return cmdStrArr, fmt.Errorf("error uploading package")
}
// 安装软件包
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo dpkg -i %s", neFilePath))
if neSoftware.NeType == "IMS" {
// 公网 PLMN地址
cmdStrArr = append(cmdStrArr, "sudo /usr/local/etc/ims/default/tools/modipplmn.sh {PUBIP} {MCC} {MNC}")
// 内网 服务地址
cmdStrArr = append(cmdStrArr, "sudo /usr/local/etc/ims/default/tools/modintraip.sh {PRIIP}")
// 10s后停止服务
cmdStrArr = append(cmdStrArr, "sudo ims-start")
cmdStrArr = append(cmdStrArr, `nohup sh -c "sleep 10s && sudo ims-stop" > /dev/null 2>&1 &`)
} else {
// 10s后停止服务
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo service %s restart", strings.ToLower(neSoftware.NeType)))
cmdStrArr = append(cmdStrArr, fmt.Sprintf(`nohup sh -c "sleep 10s && sudo service %s stop" > /dev/null 2>&1 &`, strings.ToLower(neSoftware.NeType)))
}
// 删除软件包
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo rm %s", neFilePath))
// 结束
cmdStrArr = append(cmdStrArr, fmt.Sprintf("echo '%s software install successful!'", neSoftware.NeType))
return cmdStrArr, nil
}

View File

@@ -35,12 +35,17 @@ type SysConfigController struct {
//
// GET /list
func (s *SysConfigController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
data := s.sysConfigService.SelectConfigPage(querys)
rows := data["rows"].([]model.SysConfig)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
querys := ctx.QueryMap(c)
// 多语言值转key查询
if v, ok := querys["configName"]; ok && v != "" {
querys["configName"] = i18n.TFindKeyPrefix(language, "config", v.(string))
}
data := s.sysConfigService.SelectConfigPage(querys)
rows := data["rows"].([]model.SysConfig)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysConfig) {
for i := range *arr {
(*arr)[i].ConfigName = i18n.TKey(language, (*arr)[i].ConfigName)
@@ -222,8 +227,10 @@ func (s *SysConfigController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
querys["pageNum"] = 1
querys["pageSize"] = 1000
data := s.sysConfigService.SelectConfigPage(querys)
if data["total"].(int64) == 0 {
if parse.Number(data["total"]) == 0 {
// 导出数据记录为空
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
return

View File

@@ -35,13 +35,13 @@ func (s *SysDeptController) List(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
// 部门ID
DeptID string `json:"deptId"`
DeptID string `form:"deptId"`
// 父部门ID
ParentID string `json:"parentId" `
ParentID string `form:"parentId" `
// 部门名称
DeptName string `json:"deptName" `
DeptName string `form:"deptName" `
// 部门状态0正常 1停用
Status string `json:"status"`
Status string `form:"status"`
}
err := c.ShouldBindQuery(&querys)
if err != nil {
@@ -49,6 +49,11 @@ func (s *SysDeptController) List(c *gin.Context) {
return
}
// 多语言值转key查询
if querys.DeptName != "" {
querys.DeptName = i18n.TFindKeyPrefix(language, "dept", querys.DeptName)
}
SysDeptController := model.SysDept{
DeptID: querys.DeptID,
ParentID: querys.ParentID,

View File

@@ -38,12 +38,17 @@ type SysDictDataController struct {
//
// GET /list
func (s *SysDictDataController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
data := s.sysDictDataService.SelectDictDataPage(querys)
rows := data["rows"].([]model.SysDictData)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
querys := ctx.QueryMap(c)
// 多语言值转key查询
if v, ok := querys["dictLabel"]; ok && v != "" {
querys["dictLabel"] = i18n.TFindKeyPrefix(language, "dictData", v.(string))
}
data := s.sysDictDataService.SelectDictDataPage(querys)
rows := data["rows"].([]model.SysDictData)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysDictData) {
for i := range *arr {
if strings.Contains((*arr)[i].DictType, "i18n") {
@@ -236,14 +241,21 @@ func (s *SysDictDataController) DictType(c *gin.Context) {
func (s *SysDictDataController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
data := s.sysDictDataService.SelectDictDataPage(querys)
if data["total"].(int64) == 0 {
// querys := ctx.BodyJSONMap(c)
// data := s.sysDictDataService.SelectDictDataPage(querys)
// if data["total"].(int64) == 0 {
// // 导出数据记录为空
// c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
// return
// }
// rows := data["rows"].([]model.SysDictData)
rows := s.sysDictDataService.SelectDictDataList(model.SysDictData{})
if len(rows) <= 0 {
// 导出数据记录为空
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
return
}
rows := data["rows"].([]model.SysDictData)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysDictData) {
@@ -262,11 +274,10 @@ func (s *SysDictDataController) Export(c *gin.Context) {
// 第一行表头标题
headerCells := map[string]string{
"A1": i18n.TKey(language, "dictData.export.code"),
"B1": i18n.TKey(language, "dictData.export.sort"),
"C1": i18n.TKey(language, "dictData.export.label"),
"D1": i18n.TKey(language, "dictData.export.value"),
"E1": i18n.TKey(language, "dictData.export.type"),
"F1": i18n.TKey(language, "dictData.export.status"),
"B1": i18n.TKey(language, "dictData.export.label"),
"C1": i18n.TKey(language, "dictData.export.value"),
"D1": i18n.TKey(language, "dictData.export.sort"),
"E1": i18n.TKey(language, "dictData.export.status"),
}
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
@@ -278,11 +289,10 @@ func (s *SysDictDataController) Export(c *gin.Context) {
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.DictCode,
"B" + idx: row.DictSort,
"C" + idx: row.DictLabel,
"D" + idx: row.DictValue,
"E" + idx: row.DictType,
"F" + idx: statusValue,
"B" + idx: row.DictLabel,
"C" + idx: row.DictValue,
"D" + idx: row.DictSort,
"E" + idx: statusValue,
})
}

View File

@@ -36,12 +36,17 @@ type SysDictTypeController struct {
//
// GET /list
func (s *SysDictTypeController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
data := s.sysDictTypeService.SelectDictTypePage(querys)
rows := data["rows"].([]model.SysDictType)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
querys := ctx.QueryMap(c)
// 多语言值转key查询
if v, ok := querys["dictName"]; ok && v != "" {
querys["dictName"] = i18n.TFindKeyPrefix(language, "dictType", v.(string))
}
data := s.sysDictTypeService.SelectDictTypePage(querys)
rows := data["rows"].([]model.SysDictType)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysDictType) {
for i := range *arr {
(*arr)[i].DictName = i18n.TKey(language, (*arr)[i].DictName)
@@ -239,14 +244,21 @@ func (s *SysDictTypeController) DictOptionselect(c *gin.Context) {
func (s *SysDictTypeController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
data := s.sysDictTypeService.SelectDictTypePage(querys)
if data["total"].(int64) == 0 {
// querys := ctx.BodyJSONMap(c)
// data := s.sysDictTypeService.SelectDictTypePage(querys)
// if data["total"].(int64) == 0 {
// // 导出数据记录为空
// c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
// return
// }
// rows := data["rows"].([]model.SysDictType)
rows := s.sysDictTypeService.SelectDictTypeList(model.SysDictType{})
if len(rows) <= 0 {
// 导出数据记录为空
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
return
}
rows := data["rows"].([]model.SysDictType)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysDictType) {

View File

@@ -60,17 +60,17 @@ func (s *SysLogLoginController) List(c *gin.Context) {
// 系统登录日志删除
//
// DELETE /:infoIds
// DELETE /:loginIds
func (s *SysLogLoginController) Remove(c *gin.Context) {
language := ctx.AcceptLanguage(c)
infoIds := c.Param("infoIds")
if infoIds == "" {
loginIds := c.Param("loginIds")
if loginIds == "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 处理字符转id数组后去重
ids := strings.Split(infoIds, ",")
ids := strings.Split(loginIds, ",")
uniqueIDs := parse.RemoveDuplicates(ids)
if len(uniqueIDs) <= 0 {
c.JSON(200, result.Err(nil))
@@ -121,14 +121,21 @@ func (s *SysLogLoginController) Unlock(c *gin.Context) {
func (s *SysLogLoginController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
data := s.sysLogLoginService.SelectSysLogLoginPage(querys)
if data["total"].(int64) == 0 {
// querys := ctx.BodyJSONMap(c)
// data := s.sysLogLoginService.SelectSysLogLoginPage(querys)
// if data["total"].(int64) == 0 {
// // 导出数据记录为空
// c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
// return
// }
// rows := data["rows"].([]model.SysLogLogin)
rows := s.sysLogLoginService.SelectSysLogLoginList(model.SysLogLogin{})
if len(rows) <= 0 {
// 导出数据记录为空
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
return
}
rows := data["rows"].([]model.SysLogLogin)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysLogLogin) {
@@ -147,13 +154,13 @@ func (s *SysLogLoginController) Export(c *gin.Context) {
headerCells := map[string]string{
"A1": i18n.TKey(language, "log.login.export.id"),
"B1": i18n.TKey(language, "log.login.export.userName"),
"C1": i18n.TKey(language, "log.login.export.status"),
"D1": i18n.TKey(language, "log.login.export.ip"),
"E1": i18n.TKey(language, "log.login.export.location"),
"C1": i18n.TKey(language, "log.login.export.ip"),
"D1": i18n.TKey(language, "log.login.export.location"),
"E1": i18n.TKey(language, "log.login.export.os"),
"F1": i18n.TKey(language, "log.login.export.browser"),
"G1": i18n.TKey(language, "log.login.export.os"),
"H1": i18n.TKey(language, "log.login.export.msg"),
"I1": i18n.TKey(language, "log.login.export.time"),
"G1": i18n.TKey(language, "log.login.export.status"),
"H1": i18n.TKey(language, "log.login.export.time"),
"I1": i18n.TKey(language, "log.login.export.msg"),
}
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
@@ -167,13 +174,13 @@ func (s *SysLogLoginController) Export(c *gin.Context) {
dataCells = append(dataCells, map[string]any{
"A" + idx: row.LoginID,
"B" + idx: row.UserName,
"C" + idx: statusValue,
"D" + idx: row.IPAddr,
"E" + idx: row.LoginLocation,
"C" + idx: row.IPAddr,
"D" + idx: row.LoginLocation,
"E" + idx: row.OS,
"F" + idx: row.Browser,
"G" + idx: row.OS,
"H" + idx: row.Msg,
"I" + idx: date.ParseDateToStr(row.LoginTime, date.YYYY_MM_DD_HH_MM_SS),
"G" + idx: statusValue,
"H" + idx: date.ParseDateToStr(row.LoginTime, date.YYYY_MM_DDTHH_MM_SSZ),
"I" + idx: row.Msg,
})
}

View File

@@ -35,12 +35,17 @@ type SysLogOperateController struct {
//
// GET /list
func (s *SysLogOperateController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
data := s.SysLogOperateService.SelectSysLogOperatePage(querys)
rows := data["rows"].([]model.SysLogOperate)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
querys := ctx.QueryMap(c)
// 多语言值转key查询
if v, ok := querys["title"]; ok && v != "" {
querys["title"] = i18n.TFindKeyPrefix(language, "log.operate.title", v.(string))
}
data := s.SysLogOperateService.SelectSysLogOperatePage(querys)
rows := data["rows"].([]model.SysLogOperate)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysLogOperate) {
for i := range *arr {
(*arr)[i].Title = i18n.TKey(language, (*arr)[i].Title)
@@ -97,14 +102,21 @@ func (s *SysLogOperateController) Clean(c *gin.Context) {
func (s *SysLogOperateController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
data := s.SysLogOperateService.SelectSysLogOperatePage(querys)
if data["total"].(int64) == 0 {
// querys := ctx.BodyJSONMap(c)
// data := s.SysLogOperateService.SelectSysLogOperatePage(querys)
// if data["total"].(int64) == 0 {
// // 导出数据记录为空
// c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
// return
// }
// rows := data["rows"].([]model.SysLogOperate)
rows := s.SysLogOperateService.SelectSysLogOperateList(model.SysLogOperate{})
if len(rows) <= 0 {
// 导出数据记录为空
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
return
}
rows := data["rows"].([]model.SysLogOperate)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysLogOperate) {
@@ -122,19 +134,12 @@ func (s *SysLogOperateController) Export(c *gin.Context) {
"A1": i18n.TKey(language, "log.operate.export.id"),
"B1": i18n.TKey(language, "log.operate.export.title"),
"C1": i18n.TKey(language, "log.operate.export.businessType"),
"D1": i18n.TKey(language, "log.operate.export.method"),
"E1": i18n.TKey(language, "log.operate.export.requestMethod"),
"F1": i18n.TKey(language, "log.operate.export.operatorType"),
"G1": i18n.TKey(language, "log.operate.export.operName"),
"H1": i18n.TKey(language, "log.operate.export.deptName"),
"I1": i18n.TKey(language, "log.operate.export.url"),
"J1": i18n.TKey(language, "log.operate.export.ip"),
"K1": i18n.TKey(language, "log.operate.export.location"),
"L1": i18n.TKey(language, "log.operate.export.param"),
"M1": i18n.TKey(language, "log.operate.export.msg"),
"N1": i18n.TKey(language, "log.operate.export.status"),
"O1": i18n.TKey(language, "log.operate.export.costTime"),
"P1": i18n.TKey(language, "log.operate.export.operTime"),
"D1": i18n.TKey(language, "log.operate.export.operName"),
"E1": i18n.TKey(language, "log.operate.export.method"),
"F1": i18n.TKey(language, "log.operate.export.ip"),
"G1": i18n.TKey(language, "log.operate.export.status"),
"H1": i18n.TKey(language, "log.operate.export.operTime"),
"I1": i18n.TKey(language, "log.operate.export.costTime"),
}
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
@@ -142,8 +147,36 @@ func (s *SysLogOperateController) Export(c *gin.Context) {
idx := strconv.Itoa(i + 2)
// 业务类型
businessType := ""
// 操作类别
operatorType := ""
switch row.BusinessType {
case "0":
// 业务操作类型-其它
businessType = i18n.TKey(language, "dictData.operType.other")
case "1":
// 业务操作类型-新增
businessType = i18n.TKey(language, "dictData.operType.add")
case "2":
// 业务操作类型-修改
businessType = i18n.TKey(language, "dictData.operType.edit")
case "3":
// 业务操作类型-删除
businessType = i18n.TKey(language, "dictData.operType.delete")
case "4":
// 业务操作类型-授权
businessType = i18n.TKey(language, "dictData.operType.auth")
case "5":
// 业务操作类型-导出
businessType = i18n.TKey(language, "dictData.operType.export")
case "6":
// 业务操作类型-导入
businessType = i18n.TKey(language, "dictData.operType.import")
case "7":
// 业务操作类型-强退
businessType = i18n.TKey(language, "dictData.operType.forced quit")
case "8":
// 业务操作类型-清空数据
businessType = i18n.TKey(language, "dictData.operType.clear")
}
// 状态
statusValue := i18n.TKey(language, "dictData.fail")
if row.Status == "1" {
@@ -153,19 +186,12 @@ func (s *SysLogOperateController) Export(c *gin.Context) {
"A" + idx: row.OperID,
"B" + idx: row.Title,
"C" + idx: businessType,
"D" + idx: row.Method,
"D" + idx: row.OperName,
"E" + idx: row.RequestMethod,
"F" + idx: operatorType,
"G" + idx: row.OperName,
"H" + idx: row.DeptName,
"I" + idx: row.OperURL,
"J" + idx: row.OperIP,
"K" + idx: row.OperLocation,
"L" + idx: row.OperParam,
"M" + idx: row.OperMsg,
"N" + idx: statusValue,
"O" + idx: row.CostTime,
"P" + idx: date.ParseDateToStr(row.OperTime, date.YYYY_MM_DD_HH_MM_SS),
"F" + idx: row.OperIP,
"G" + idx: statusValue,
"H" + idx: date.ParseDateToStr(row.OperTime, date.YYYY_MM_DDTHH_MM_SSZ),
"I" + idx: row.CostTime,
})
}

View File

@@ -33,9 +33,10 @@ type SysMenuController struct {
//
// GET /list
func (s *SysMenuController) List(c *gin.Context) {
language := ctx.AcceptLanguage(c)
query := model.SysMenu{}
if v, ok := c.GetQuery("menuName"); ok && v != "" {
query.MenuName = v
query.MenuName = i18n.TFindKeyPrefix(language, "menu", v)
}
if v, ok := c.GetQuery("status"); ok && v != "" {
query.Status = v
@@ -48,7 +49,6 @@ func (s *SysMenuController) List(c *gin.Context) {
data := s.sysMenuService.SelectMenuList(query, userId)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
var converI18n func(language string, arr *[]model.SysMenu)
converI18n = func(language string, arr *[]model.SysMenu) {
for i := range *arr {

View File

@@ -8,6 +8,7 @@ import (
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo/result"
@@ -35,12 +36,17 @@ type SysPostController struct {
//
// GET /list
func (s *SysPostController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
data := s.sysPostService.SelectPostPage(querys)
rows := data["rows"].([]model.SysPost)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
querys := ctx.QueryMap(c)
// 多语言值转key查询
if v, ok := querys["postName"]; ok && v != "" {
querys["postName"] = i18n.TFindKeyPrefix(language, "post", v.(string))
}
data := s.sysPostService.SelectPostPage(querys)
rows := data["rows"].([]model.SysPost)
// 闭包函数处理多语言
converI18n := func(language string, arr *[]model.SysPost) {
for i := range *arr {
(*arr)[i].PostName = i18n.TKey(language, (*arr)[i].PostName)
@@ -204,7 +210,11 @@ func (s *SysPostController) Remove(c *gin.Context) {
func (s *SysPostController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
// querys := ctx.BodyJSONMap(c)
querys := map[string]any{
"pageNum": 1,
"pageSize": 1000,
}
data := s.sysPostService.SelectPostPage(querys)
if data["total"].(int64) == 0 {
// 导出数据记录为空
@@ -227,10 +237,11 @@ func (s *SysPostController) Export(c *gin.Context) {
// 第一行表头标题
headerCells := map[string]string{
"A1": i18n.TKey(language, "post.export.id"),
"B1": i18n.TKey(language, "post.export.code"),
"C1": i18n.TKey(language, "post.export.name"),
"B1": i18n.TKey(language, "post.export.name"),
"C1": i18n.TKey(language, "post.export.code"),
"D1": i18n.TKey(language, "post.export.sort"),
"E1": i18n.TKey(language, "post.export.status"),
"F1": i18n.TKey(language, "post.export.time"),
}
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
@@ -242,10 +253,11 @@ func (s *SysPostController) Export(c *gin.Context) {
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.PostID,
"B" + idx: row.PostCode,
"C" + idx: row.PostName,
"B" + idx: row.PostName,
"C" + idx: row.PostCode,
"D" + idx: row.PostSort,
"E" + idx: statusValue,
"F" + idx: date.ParseDateToStr(row.CreateTime, date.YYYY_MM_DDTHH_MM_SSZ),
})
}

View File

@@ -9,6 +9,7 @@ import (
"be.ems/src/framework/constants/admin"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo/result"
@@ -42,13 +43,18 @@ type SysRoleController struct {
//
// GET /list
func (s *SysRoleController) List(c *gin.Context) {
language := ctx.AcceptLanguage(c)
querys := ctx.QueryMap(c)
// 多语言值转key查询
if v, ok := querys["roleName"]; ok && v != "" {
querys["roleName"] = i18n.TFindKeyPrefix(language, "role", v.(string))
}
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
data := s.sysRoleService.SelectRolePage(querys, dataScopeSQL)
rows := data["rows"].([]model.SysRole)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
converI18n := func(language string, arr *[]model.SysRole) {
for i := range *arr {
(*arr)[i].RoleName = i18n.TKey(language, (*arr)[i].RoleName)
@@ -407,7 +413,11 @@ func (s *SysRoleController) AuthUserChecked(c *gin.Context) {
func (s *SysRoleController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
// querys := ctx.BodyJSONMap(c)
querys := map[string]any{
"pageNum": 1,
"pageSize": 1000,
}
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
data := s.sysRoleService.SelectRolePage(querys, dataScopeSQL)
if data["total"].(int64) == 0 {
@@ -434,23 +444,24 @@ func (s *SysRoleController) Export(c *gin.Context) {
"B1": i18n.TKey(language, "role.export.name"),
"C1": i18n.TKey(language, "role.export.key"),
"D1": i18n.TKey(language, "role.export.sort"),
"E1": i18n.TKey(language, "role.export.dataScope"),
"F1": i18n.TKey(language, "role.export.status"),
"E1": i18n.TKey(language, "role.export.status"),
"F1": i18n.TKey(language, "role.export.time"),
// "F1": i18n.TKey(language, "role.export.dataScope"),
}
// 读取系统角色数据范围字典数据
dictSysRoleDatascope := s.sysDictDataService.SelectDictDataByType("sys_role_datascope")
// dictSysRoleDatascope := s.sysDictDataService.SelectDictDataByType("sys_role_datascope")
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
for i, row := range rows {
idx := strconv.Itoa(i + 2)
// 数据范围
dataScope := row.DataScope
for _, v := range dictSysRoleDatascope {
if row.DataScope == v.DictValue {
dataScope = i18n.TKey(language, v.DictLabel)
break
}
}
// dataScope := row.DataScope
// for _, v := range dictSysRoleDatascope {
// if row.DataScope == v.DictValue {
// dataScope = i18n.TKey(language, v.DictLabel)
// break
// }
// }
// 角色状态
statusValue := i18n.TKey(language, "dictData.disable")
if row.Status == "1" {
@@ -461,8 +472,9 @@ func (s *SysRoleController) Export(c *gin.Context) {
"B" + idx: row.RoleName,
"C" + idx: row.RoleKey,
"D" + idx: row.RoleSort,
"E" + idx: dataScope,
"F" + idx: statusValue,
"E" + idx: statusValue,
"F" + idx: date.ParseDateToStr(row.CreateTime, date.YYYY_MM_DDTHH_MM_SSZ),
// "F" + idx: dataScope,
})
}

View File

@@ -473,7 +473,11 @@ func (s *SysUserController) Status(c *gin.Context) {
func (s *SysUserController) Export(c *gin.Context) {
language := ctx.AcceptLanguage(c)
// 查询结果,根据查询条件结果,单页最大值限制
querys := ctx.BodyJSONMap(c)
// querys := ctx.BodyJSONMap(c)
querys := map[string]any{
"pageNum": 1,
"pageSize": 1000,
}
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "u")
data := s.sysUserService.SelectUserPage(querys, dataScopeSQL)
if data["total"].(int64) == 0 {
@@ -503,31 +507,31 @@ func (s *SysUserController) Export(c *gin.Context) {
"A1": i18n.TKey(language, "user.export.id"),
"B1": i18n.TKey(language, "user.export.name"),
"C1": i18n.TKey(language, "user.export.nick"),
"D1": i18n.TKey(language, "user.export.email"),
"E1": i18n.TKey(language, "user.export.phone"),
"F1": i18n.TKey(language, "user.export.sex"),
"G1": i18n.TKey(language, "user.export.status"),
"H1": i18n.TKey(language, "user.export.role"),
"I1": i18n.TKey(language, "user.export.deptID"),
"J1": i18n.TKey(language, "user.export.deptName"),
"K1": i18n.TKey(language, "user.export.deptLeader"),
"L1": i18n.TKey(language, "user.export.loginIP"),
"M1": i18n.TKey(language, "user.export.loginDate"),
"D1": i18n.TKey(language, "user.export.role"),
"E1": i18n.TKey(language, "user.export.deptName"),
"F1": i18n.TKey(language, "user.export.loginIP"),
"G1": i18n.TKey(language, "user.export.loginDate"),
"H1": i18n.TKey(language, "user.export.status"),
// "F1": i18n.TKey(language, "user.export.sex"),
// "E1": i18n.TKey(language, "user.export.phone"),
// "D1": i18n.TKey(language, "user.export.email"),
// "I1": i18n.TKey(language, "user.export.deptID"),
// "K1": i18n.TKey(language, "user.export.deptLeader"),
}
// 读取用户性别字典数据
dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex")
// dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex")
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
for i, row := range rows {
idx := strconv.Itoa(i + 2)
// 用户性别
sysUserSex := row.Sex
for _, v := range dictSysUserSex {
if row.Sex == v.DictValue {
sysUserSex = i18n.TKey(language, v.DictLabel)
break
}
}
// sysUserSex := row.Sex
// for _, v := range dictSysUserSex {
// if row.Sex == v.DictValue {
// sysUserSex = i18n.TKey(language, v.DictLabel)
// break
// }
// }
// 帐号状态
statusValue := i18n.TKey(language, "dictData.disable")
if row.Status == "1" {
@@ -536,24 +540,22 @@ func (s *SysUserController) Export(c *gin.Context) {
// 用户角色, 默认导出首个
userRole := ""
if len(row.Roles) > 0 {
roleID := row.Roles[0].RoleID
roleName := i18n.TKey(language, row.Roles[0].RoleName)
userRole = fmt.Sprintf("%s-%s", roleID, roleName)
userRole = i18n.TKey(language, row.Roles[0].RoleName)
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.UserID,
"B" + idx: row.UserName,
"C" + idx: row.NickName,
"D" + idx: row.Email,
"E" + idx: row.PhoneNumber,
"F" + idx: sysUserSex,
"G" + idx: statusValue,
"H" + idx: userRole,
"I" + idx: row.Dept.DeptID,
"J" + idx: row.Dept.DeptName,
"K" + idx: row.Dept.Leader,
"L" + idx: row.LoginIP,
"M" + idx: date.ParseDateToStr(row.LoginDate, date.YYYY_MM_DD_HH_MM_SS),
"D" + idx: userRole,
"E" + idx: row.Dept.DeptName,
"F" + idx: row.LoginIP,
"G" + idx: date.ParseDateToStr(row.LoginDate, date.YYYY_MM_DD_HH_MM_SS),
"H" + idx: statusValue,
// "E" + idx: row.PhoneNumber,
// "F" + idx: sysUserSex,
// "D" + idx: row.Email,
// "I" + idx: row.Dept.DeptID,
// "K" + idx: row.Dept.Leader,
})
}

View File

@@ -7,7 +7,6 @@ import (
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/repo"
"be.ems/src/modules/system/model"
@@ -79,8 +78,7 @@ func (r *SysConfigImpl) SelectConfigPage(query map[string]any) map[string]any {
}
if ok && beginTime != "" {
conditions = append(conditions, "create_time >= ?")
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
params = append(params, beginDate.UnixMilli())
params = append(params, parse.Number(beginTime.(string)))
}
endTime, ok := query["endTime"]
if !ok {
@@ -88,8 +86,7 @@ func (r *SysConfigImpl) SelectConfigPage(query map[string]any) map[string]any {
}
if ok && endTime != "" {
conditions = append(conditions, "create_time <= ?")
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
params = append(params, endDate.UnixMilli())
params = append(params, parse.Number(endTime.(string)))
}
// 构建查询条件语句

View File

@@ -69,7 +69,7 @@ func (r *SysDictDataImpl) SelectDictDataPage(query map[string]any) map[string]an
}
if v, ok := query["dictLabel"]; ok && v != "" {
conditions = append(conditions, "dict_label like concat(?, '%')")
params = append(params, v)
params = append(params, strings.TrimSpace(v.(string)))
}
if v, ok := query["status"]; ok && v != "" {
conditions = append(conditions, "status = ?")

View File

@@ -7,7 +7,6 @@ import (
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/repo"
"be.ems/src/modules/system/model"
@@ -62,11 +61,11 @@ func (r *SysDictTypeImpl) SelectDictTypePage(query map[string]any) map[string]an
var params []any
if v, ok := query["dictName"]; ok && v != "" {
conditions = append(conditions, "dict_name like concat(?, '%')")
params = append(params, v)
params = append(params, strings.TrimSpace(v.(string)))
}
if v, ok := query["dictType"]; ok && v != "" {
conditions = append(conditions, "dict_type like concat(?, '%')")
params = append(params, v)
params = append(params, strings.TrimSpace(v.(string)))
}
if v, ok := query["status"]; ok && v != "" {
conditions = append(conditions, "status = ?")
@@ -78,8 +77,7 @@ func (r *SysDictTypeImpl) SelectDictTypePage(query map[string]any) map[string]an
}
if ok && beginTime != "" {
conditions = append(conditions, "create_time >= ?")
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
params = append(params, beginDate.UnixMilli())
params = append(params, parse.Number(beginTime.(string)))
}
endTime, ok := query["endTime"]
if !ok {
@@ -87,8 +85,7 @@ func (r *SysDictTypeImpl) SelectDictTypePage(query map[string]any) map[string]an
}
if ok && endTime != "" {
conditions = append(conditions, "create_time <= ?")
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
params = append(params, endDate.UnixMilli())
params = append(params, parse.Number(endTime.(string)))
}
// 构建查询条件语句

View File

@@ -6,7 +6,6 @@ import (
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/repo"
"be.ems/src/modules/system/model"
@@ -76,8 +75,7 @@ func (r *SysLogLoginImpl) SelectSysLogLoginPage(query map[string]any) map[string
}
if ok && beginTime != "" {
conditions = append(conditions, "login_time >= ?")
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD_HH_MM_SS)
params = append(params, beginDate.UnixMilli())
params = append(params, parse.Number(beginTime.(string)))
}
endTime, ok := query["endTime"]
if !ok {
@@ -85,8 +83,7 @@ func (r *SysLogLoginImpl) SelectSysLogLoginPage(query map[string]any) map[string
}
if ok && endTime != "" {
conditions = append(conditions, "login_time <= ?")
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD_HH_MM_SS)
params = append(params, endDate.UnixMilli())
params = append(params, parse.Number(endTime.(string)))
}
// 构建查询条件语句

View File

@@ -6,7 +6,6 @@ import (
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/repo"
"be.ems/src/modules/system/model"
@@ -69,7 +68,7 @@ func (r *SysLogOperateImpl) SelectSysLogOperatePage(query map[string]any) map[st
var params []any
if v, ok := query["title"]; ok && v != "" {
conditions = append(conditions, "title like concat(?, '%')")
params = append(params, v)
params = append(params, strings.TrimSpace(v.(string)))
}
if v, ok := query["businessType"]; ok && v != "" {
conditions = append(conditions, "business_type = ?")
@@ -77,7 +76,7 @@ func (r *SysLogOperateImpl) SelectSysLogOperatePage(query map[string]any) map[st
}
if v, ok := query["operName"]; ok && v != "" {
conditions = append(conditions, "oper_name like concat(?, '%')")
params = append(params, v)
params = append(params, strings.TrimSpace(v.(string)))
}
if v, ok := query["status"]; ok && v != "" {
conditions = append(conditions, "status = ?")
@@ -89,8 +88,7 @@ func (r *SysLogOperateImpl) SelectSysLogOperatePage(query map[string]any) map[st
}
if ok && beginTime != "" {
conditions = append(conditions, "oper_time >= ?")
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD_HH_MM_SS)
params = append(params, beginDate.UnixMilli())
params = append(params, parse.Number(beginTime.(string)))
}
endTime, ok := query["endTime"]
if !ok {
@@ -98,8 +96,7 @@ func (r *SysLogOperateImpl) SelectSysLogOperatePage(query map[string]any) map[st
}
if ok && endTime != "" {
conditions = append(conditions, "oper_time <= ?")
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD_HH_MM_SS)
params = append(params, endDate.UnixMilli())
params = append(params, parse.Number(endTime.(string)))
}
// 构建查询条件语句

View File

@@ -7,7 +7,6 @@ import (
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/repo"
"be.ems/src/modules/system/model"
@@ -91,8 +90,7 @@ func (r *SysRoleImpl) SelectRolePage(query map[string]any, dataScopeSQL string)
}
if ok && beginTime != "" {
conditions = append(conditions, "r.create_time >= ?")
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
params = append(params, beginDate.UnixMilli())
params = append(params, parse.Number(beginTime.(string)))
}
endTime, ok := query["endTime"]
if !ok {
@@ -100,8 +98,7 @@ func (r *SysRoleImpl) SelectRolePage(query map[string]any, dataScopeSQL string)
}
if ok && endTime != "" {
conditions = append(conditions, "r.create_time <= ?")
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
params = append(params, endDate.UnixMilli())
params = append(params, parse.Number(endTime.(string)))
}
if v, ok := query["deptId"]; ok && v != "" {
conditions = append(conditions, `(u.dept_id = ? or u.dept_id in (
@@ -112,7 +109,7 @@ func (r *SysRoleImpl) SelectRolePage(query map[string]any, dataScopeSQL string)
}
// 构建查询条件语句
whereSql := " where r.del_flag = '0' "
whereSql := " where r.del_flag = '0' and r.role_id != '1' "
if len(conditions) > 0 {
whereSql += " and " + strings.Join(conditions, " and ")
}

View File

@@ -8,7 +8,6 @@ import (
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/crypto"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/repo"
"be.ems/src/modules/system/model"
@@ -156,8 +155,7 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string)
}
if ok && beginTime != "" {
conditions = append(conditions, "u.login_date >= ?")
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
params = append(params, beginDate.UnixMilli())
params = append(params, parse.Number(beginTime.(string)))
}
endTime, ok := query["endTime"]
if !ok {
@@ -165,8 +163,7 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string)
}
if ok && endTime != "" {
conditions = append(conditions, "u.login_date <= ?")
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
params = append(params, endDate.UnixMilli())
params = append(params, parse.Number(endTime.(string)))
}
if v, ok := query["deptId"]; ok && v != "" {
conditions = append(conditions, "(u.dept_id = ? or u.dept_id in ( select t.dept_id from sys_dept t where find_in_set(?, ancestors) ))")
@@ -175,7 +172,7 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string)
}
// 构建查询条件语句
whereSql := " where u.del_flag = '0' "
whereSql := " where u.del_flag = '0' and u.user_id != '1' "
if len(conditions) > 0 {
whereSql += " and " + strings.Join(conditions, " and ")
}
@@ -515,7 +512,8 @@ func (r *SysUserImpl) UpdateUser(sysUser model.SysUser) int64 {
// DeleteUserByIds 批量删除用户信息
func (r *SysUserImpl) DeleteUserByIds(userIds []string) int64 {
placeholder := repo.KeyPlaceholderByQuery(len(userIds))
sql := "update sys_user set del_flag = '1' where user_id in (" + placeholder + ")"
username := "CASE WHEN user_name = '' THEN user_name WHEN LENGTH(user_name) >= 36 THEN CONCAT('del_', SUBSTRING(user_name, 5, 36)) ELSE CONCAT('del_', user_name) END"
sql := fmt.Sprintf("update sys_user set del_flag = '1', user_name = %s where user_id in (%s)", username, placeholder)
parameters := repo.ConvertIdsSlice(userIds)
results, err := datasource.ExecDB("", sql, parameters)
if err != nil {

View File

@@ -32,7 +32,7 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string)
// SelectUserList 根据条件查询用户列表
func (r *SysUserImpl) SelectUserList(sysUser model.SysUser, dataScopeSQL string) []model.SysUser {
return []model.SysUser{}
return r.sysUserRepository.SelectUserList(sysUser, dataScopeSQL)
}
// SelectAllocatedPage 根据条件分页查询分配用户角色列表

View File

@@ -143,7 +143,8 @@ func (s *TcpdumpImpl) DumpUPF(neType, neId, cmdStr string) (string, string, erro
timeStr := date.ParseDateToStr(time.Now(), date.YYYYMMDDHHMMSS)
fileName := fmt.Sprintf("%s_%s", timeStr, neTypeID)
// UPF标准版本telnet脚本
scriptStr := "set pcapCmd [lindex $argv 0]\nspawn telnet localhost 5002\nexpect \"upfd1# \"\nsend \"$pcapCmd\\n\"\nexpect \"upfd1# \"\nsend \"quit\\n\"\nexpect \"eof\""
scriptStr := "set pcapCmd [lindex $argv 0]\nspawn telnet " + neInfo.IP + " 5002\nexpect \"upfd1# \"\nsend \"$pcapCmd\\n\"\nexpect \"upfd1# \"\nsend \"quit\\n\"\nexpect \"eof\""
// scriptStr := "set pcapCmd [lindex $argv 0]\nspawn telnet localhost 5002\nexpect \"upfd1# \"\nsend \"$pcapCmd\\n\"\nexpect \"upfd1# \"\nsend \"quit\\n\"\nexpect \"eof\""
writePcapFile := fmt.Sprintf("echo '%s' > pcapUPF.sh\n %s chmod +x pcapUPF.sh", scriptStr, withSudo)
writeLogFile := fmt.Sprintf("> %s.log 2>&1 \ncat %s.log", fileName, fileName)

View File

@@ -196,11 +196,11 @@ func (s *WSController) SSH(c *gin.Context) {
wsClient.MsgChan <- msgByte
// 退出ssh登录
if strings.LastIndex(outputStr, "logout\r\n") != -1 {
time.Sleep(1 * time.Second)
s.wsService.CloseClient(wsClient.ID)
return
}
// if strings.LastIndex(outputStr, "logout\r\n") != -1 {
// time.Sleep(1 * time.Second)
// s.wsService.CloseClient(wsClient.ID)
// return
// }
}
}
}()
@@ -283,11 +283,11 @@ func (s *WSController) Telnet(c *gin.Context) {
wsClient.MsgChan <- msgByte
// 退出telnet登录
if strings.LastIndex(outputStr, "logout\r\n") != -1 {
time.Sleep(1 * time.Second)
s.wsService.CloseClient(wsClient.ID)
return
}
// if strings.LastIndex(outputStr, "logout\r\n") != -1 {
// time.Sleep(1 * time.Second)
// s.wsService.CloseClient(wsClient.ID)
// return
// }
}
}
}()

View File

@@ -3,6 +3,7 @@ package service
import (
"encoding/json"
"fmt"
"io"
"time"
"be.ems/src/framework/logger"
@@ -83,6 +84,11 @@ func (s *WSReceiveImpl) AsyncReceive(client *model.WSClient, reqMsg model.WSRequ
logger.Warnf("ws AsyncReceive UID %s err: %s", client.BindUid, err.Error())
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
client.MsgChan <- msgByte
if err == io.EOF {
// 等待1s后关闭连接
time.Sleep(1 * time.Second)
client.StopChan <- struct{}{}
}
return
}
if len(resByte) > 0 {