From af93652e3dec4e26e11ea790664f8cfa0959d93e Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Mon, 26 Feb 2024 12:00:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E7=BD=91=E5=85=83?= =?UTF-8?q?=E4=B8=BB=E6=9C=BA=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network_element/controller/ne_host.go | 273 ++++++++++++ src/modules/network_element/model/ne_host.go | 40 ++ .../network_element/network_element.go | 38 ++ .../network_element/repository/ne_host.go | 27 ++ .../repository/ne_hosti.impl.go | 407 ++++++++++++++++++ .../network_element/service/ne_host.go | 30 ++ .../network_element/service/ne_host.impl.go | 92 ++++ 7 files changed, 907 insertions(+) create mode 100644 src/modules/network_element/controller/ne_host.go create mode 100644 src/modules/network_element/model/ne_host.go create mode 100644 src/modules/network_element/repository/ne_host.go create mode 100644 src/modules/network_element/repository/ne_hosti.impl.go create mode 100644 src/modules/network_element/service/ne_host.go create mode 100644 src/modules/network_element/service/ne_host.impl.go diff --git a/src/modules/network_element/controller/ne_host.go b/src/modules/network_element/controller/ne_host.go new file mode 100644 index 00000000..cf3cd230 --- /dev/null +++ b/src/modules/network_element/controller/ne_host.go @@ -0,0 +1,273 @@ +package controller + +import ( + "strings" + + "ems.agt/src/framework/i18n" + "ems.agt/src/framework/utils/ctx" + "ems.agt/src/framework/utils/parse" + "ems.agt/src/framework/utils/ssh" + "ems.agt/src/framework/utils/telnet" + "ems.agt/src/framework/vo/result" + "ems.agt/src/modules/network_element/model" + neService "ems.agt/src/modules/network_element/service" + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" +) + +// 实例化控制层 NeHostController 结构体 +var NewNeHost = &NeHostController{ + neHostService: neService.NewNeHostImpl, +} + +// 网元主机连接请求 +// +// PATH /host +type NeHostController struct { + // 网元主机连接服务 + neHostService neService.INeHost +} + +// 网元主机列表 +// +// GET /list +func (s *NeHostController) List(c *gin.Context) { + querys := ctx.QueryMap(c) + data := s.neHostService.SelectPage(querys) + + rows := data["rows"].([]model.NeHost) + arr := &rows + for i := range *arr { + (*arr)[i].Password = "-" + (*arr)[i].PrivateKey = "-" + (*arr)[i].PassPhrase = "-" + } + + c.JSON(200, result.Ok(data)) +} + +// 网元主机信息 +// +// GET /:hostId +func (s *NeHostController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) + hostId := c.Param("hostId") + if hostId == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + neHost := s.neHostService.SelectById(hostId) + if neHost.HostID != hostId { + // 没有可访问主机信息数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.noData"))) + return + } + + c.JSON(200, result.OkData(neHost)) +} + +// 网元主机新增 +// +// POST / +func (s *NeHostController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.NeHost + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil || body.HostID != "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 检查属性值唯一 + uniqueHost := s.neHostService.CheckUniqueHostTitle(body.GroupID, body.Title, body.HostType, "") + if !uniqueHost { + // 主机信息操作【%s】失败,同组内名称已存在 + msg := i18n.TTemplate(language, "neHost.errKeyExists", map[string]any{"name": body.Title}) + c.JSON(200, result.ErrMsg(msg)) + return + } + + body.CreateBy = ctx.LoginUserToUserName(c) + insertId := s.neHostService.Insert(body) + if insertId != "" { + c.JSON(200, result.Ok(nil)) + return + } + c.JSON(200, result.Err(nil)) +} + +// 网元主机修改 +// +// PUT / +func (s *NeHostController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.NeHost + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil || body.HostID == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 检查属性值唯一 + uniqueHost := s.neHostService.CheckUniqueHostTitle(body.GroupID, body.Title, body.HostType, body.HostID) + if !uniqueHost { + // 主机信息操作【%s】失败,同组内名称已存在 + msg := i18n.TTemplate(language, "neHost.errKeyExists", map[string]any{"name": body.Title}) + c.JSON(200, result.ErrMsg(msg)) + return + } + + // 检查是否存在 + neHost := s.neHostService.SelectById(body.HostID) + if neHost.HostID != body.HostID { + // 没有可访问主机信息数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.noData"))) + return + } + + body.UpdateBy = ctx.LoginUserToUserName(c) + rows := s.neHostService.Update(body) + if rows > 0 { + c.JSON(200, result.Ok(nil)) + return + } + c.JSON(200, result.Err(nil)) +} + +// 网元主机删除 +// +// DELETE /:hostIds +func (s *NeHostController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) + hostIds := c.Param("hostIds") + if hostIds == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + // 处理字符转id数组后去重 + ids := strings.Split(hostIds, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + c.JSON(200, result.Err(nil)) + return + } + rows, err := s.neHostService.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)) +} + +// 网元主机测试连接 +// +// POST /test +func (s *NeHostController) Test(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 + } + + if body.HostType == "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() + c.JSON(200, result.Ok(nil)) + return + } + + if body.HostType == "telnet" { + var connTelnet telnet.ConnTelnet + body.CopyTo(&connTelnet) + + client, err := connTelnet.NewClient() + if err != nil { + // 连接主机失败,请检查连接参数后重试 + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo"))) + return + } + defer client.Close() + c.JSON(200, result.Ok(nil)) + return + } +} + +// 网元主机发送命令 +// +// POST /cmd +func (s *NeHostController) Cmd(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body struct { + HostID string `json:"hostId" binding:"required"` // 主机ID + Cmd string `json:"cmd" binding:"required"` // 执行命令 + } + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 检查是否存在 + neHost := s.neHostService.SelectById(body.HostID) + if neHost.HostID != body.HostID { + // 没有可访问主机信息数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.noData"))) + return + } + + if neHost.HostType == "ssh" { + var connSSH ssh.ConnSSH + neHost.CopyTo(&connSSH) + + client, err := connSSH.NewClient() + if err != nil { + // 连接主机失败,请检查连接参数后重试 + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo"))) + return + } + defer client.Close() + + // 执行命令 + output, err := client.RunCMD(body.Cmd) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.OkData(output)) + return + } + + if neHost.HostType == "telnet" { + var connTelnet telnet.ConnTelnet + neHost.CopyTo(&connTelnet) + + client, err := connTelnet.NewClient() + if err != nil { + // 连接主机失败,请检查连接参数后重试 + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo"))) + return + } + defer client.Close() + + // 执行命令 + output, err := client.RunCMD(body.Cmd) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.OkData(output)) + return + } +} diff --git a/src/modules/network_element/model/ne_host.go b/src/modules/network_element/model/ne_host.go new file mode 100644 index 00000000..40620338 --- /dev/null +++ b/src/modules/network_element/model/ne_host.go @@ -0,0 +1,40 @@ +package model + +import "encoding/json" + +// NeHost 网元主机表 ne_host +type NeHost struct { + HostID string `json:"hostId" gorm:"column:host_id"` // 主机主键 + HostType string `json:"hostType" gorm:"column:host_type" binding:"oneof=ssh telnet"` // 主机类型 ssh telnet + GroupID string `json:"groupId" gorm:"column:group_id"` // 分组(0默认) + Title string `json:"title" gorm:"column:title"` // 标题名称 + Addr string `json:"addr" gorm:"column:addr" binding:"required"` // 主机地址 + Port int64 `json:"port" gorm:"column:port" binding:"required,number,max=65535,min=1"` // SSH端口 + User string `json:"user" gorm:"column:user" binding:"required"` // 主机用户名 + AuthMode string `json:"authMode" gorm:"column:auth_mode" binding:"oneof=0 1"` // 认证模式(0密码 1主机私钥) + Password string `json:"password" gorm:"column:password"` // 认证密码 + PrivateKey string `json:"privateKey" gorm:"column:private_key"` // 认证私钥 + PassPhrase string `json:"passPhrase" gorm:"column:pass_phrase"` // 认证私钥密码 + Remark string `json:"remark" gorm:"column:remark"` // 备注 + 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 表名称 +func (NeHost) TableName() string { + return "ne_host" +} + +// CopyTo 网元主机信息将josn同key名的结构体复制给另一个结构体 +func (m *NeHost) CopyTo(to interface{}) error { + b, err := json.Marshal(m) + if err != nil { + return err + } + if err = json.Unmarshal(b, to); err != nil { + return err + } + return nil +} diff --git a/src/modules/network_element/network_element.go b/src/modules/network_element/network_element.go index 7f7f7e3c..deed21c7 100644 --- a/src/modules/network_element/network_element.go +++ b/src/modules/network_element/network_element.go @@ -54,6 +54,44 @@ func Setup(router *gin.Engine) { ) } + // 网元主机 + neHostGroup := neGroup.Group("/host") + { + neHostGroup.GET("/list", + middleware.PreAuthorize(nil), + controller.NewNeHost.List, + ) + neHostGroup.GET("/:hostId", + middleware.PreAuthorize(nil), + controller.NewNeHost.Info, + ) + neHostGroup.POST("", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neHost", collectlogs.BUSINESS_TYPE_INSERT)), + controller.NewNeHost.Add, + ) + neHostGroup.PUT("", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neHost", collectlogs.BUSINESS_TYPE_UPDATE)), + controller.NewNeHost.Edit, + ) + neHostGroup.DELETE("/:hostIds", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neHost", collectlogs.BUSINESS_TYPE_DELETE)), + controller.NewNeHost.Remove, + ) + neHostGroup.POST("/test", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neHost", collectlogs.BUSINESS_TYPE_OTHER)), + controller.NewNeHost.Test, + ) + neHostGroup.POST("/cmd", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neHost", collectlogs.BUSINESS_TYPE_OTHER)), + controller.NewNeHost.Cmd, + ) + } + // UDM鉴权用户信息 udmAuthGroup := neGroup.Group("/udm/auth") { diff --git a/src/modules/network_element/repository/ne_host.go b/src/modules/network_element/repository/ne_host.go new file mode 100644 index 00000000..d5441bc8 --- /dev/null +++ b/src/modules/network_element/repository/ne_host.go @@ -0,0 +1,27 @@ +package repository + +import "ems.agt/src/modules/network_element/model" + +// INeHost 网元主机连接 数据层接口 +type INeHost interface { + // SelectPage 根据条件分页查询字典类型 + SelectPage(query map[string]any) map[string]any + + // SelectList 根据实体查询 + SelectList(neHost model.NeHost) []model.NeHost + + // SelectByIds 通过ID查询 + SelectByIds(hostIds []string) []model.NeHost + + // Insert 新增信息 + Insert(neHost model.NeHost) string + + // Update 修改信息 + Update(neHost model.NeHost) int64 + + // DeleteByIds 批量删除网元主机连接信息 + DeleteByIds(hostIds []string) int64 + + // CheckUniqueNeHost 校验主机是否唯一 + CheckUniqueNeHost(neHost model.NeHost) string +} diff --git a/src/modules/network_element/repository/ne_hosti.impl.go b/src/modules/network_element/repository/ne_hosti.impl.go new file mode 100644 index 00000000..f4b5c4c2 --- /dev/null +++ b/src/modules/network_element/repository/ne_hosti.impl.go @@ -0,0 +1,407 @@ +package repository + +import ( + "strings" + "time" + + "ems.agt/src/framework/datasource" + "ems.agt/src/framework/logger" + "ems.agt/src/framework/utils/crypto" + "ems.agt/src/framework/utils/parse" + "ems.agt/src/framework/utils/repo" + "ems.agt/src/modules/network_element/model" +) + +// 实例化数据层 NewNeHostImpl 结构体 +var NewNeHostImpl = &NeHostImpl{ + selectSql: `select + host_id, host_type, group_id, title, addr, port, user, auth_mode, password, private_key, pass_phrase, remark, create_by, create_time, update_by, update_time + from ne_host`, + + resultMap: map[string]string{ + "host_id": "HostID", + "host_type": "HostType", + "group_id": "GroupID", + "title": "Title", + "addr": "Addr", + "port": "Port", + "user": "User", + "auth_mode": "AuthMode", + "password": "Password", + "private_key": "PrivateKey", + "private_password": "PassPhrase", + "remark": "Remark", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", + "update_time": "UpdateTime", + }, +} + +// NeHostImpl 网元主机连接 数据层处理 +type NeHostImpl struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *NeHostImpl) convertResultRows(rows []map[string]any) []model.NeHost { + arr := make([]model.NeHost, 0) + for _, row := range rows { + item := model.NeHost{} + 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 *NeHostImpl) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["hostType"]; ok && v != "" { + conditions = append(conditions, "host_type = ?") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["groupId"]; ok && v != "" { + conditions = append(conditions, "group_id = ?") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["title"]; ok && v != "" { + conditions = append(conditions, "title 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_host" + 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 *NeHostImpl) SelectList(neHost model.NeHost) []model.NeHost { + // 查询条件拼接 + var conditions []string + var params []any + if neHost.HostType != "" { + conditions = append(conditions, "host_type = ?") + params = append(params, neHost.GroupID) + } + if neHost.GroupID != "" { + conditions = append(conditions, "group_id = ?") + params = append(params, neHost.GroupID) + } + if neHost.Title != "" { + conditions = append(conditions, "title like concat(?, '%')") + params = append(params, neHost.Title) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by update_time asc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIds 通过ID查询 +func (r *NeHostImpl) SelectByIds(hostIds []string) []model.NeHost { + placeholder := repo.KeyPlaceholderByQuery(len(hostIds)) + querySql := r.selectSql + " where host_id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(hostIds) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.NeHost{} + } + // 转换实体 + rows := r.convertResultRows(results) + arr := &rows + for i := range *arr { + passwordDe, err := crypto.StringDecryptByAES((*arr)[i].Password) + if err != nil { + logger.Errorf("selectById %s StringDecryptByAES : %v", (*arr)[i].HostID, err.Error()) + (*arr)[i].Password = "" + } else { + (*arr)[i].Password = passwordDe + } + privateKeyDe, err := crypto.StringDecryptByAES((*arr)[i].PrivateKey) + if err != nil { + logger.Errorf("selectById %s StringDecryptByAES : %v", (*arr)[i].HostID, err.Error()) + (*arr)[i].PrivateKey = "" + } else { + (*arr)[i].PrivateKey = privateKeyDe + } + passPhraseDe, err := crypto.StringDecryptByAES((*arr)[i].PassPhrase) + if err != nil { + logger.Errorf("selectById %s StringDecryptByAES : %v", (*arr)[i].HostID, err.Error()) + (*arr)[i].PassPhrase = "" + } else { + (*arr)[i].PassPhrase = passPhraseDe + } + } + return rows +} + +// CheckUniqueNeHost 校验主机是否唯一 +func (r *NeHostImpl) CheckUniqueNeHost(neHost model.NeHost) string { + // 查询条件拼接 + var conditions []string + var params []any + if neHost.HostType != "" { + conditions = append(conditions, "host_type = ?") + params = append(params, neHost.HostType) + } + if neHost.GroupID != "" { + conditions = append(conditions, "group_id = ?") + params = append(params, neHost.GroupID) + } + if neHost.Title != "" { + conditions = append(conditions, "title = ?") + params = append(params, neHost.Title) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } else { + return "" + } + + // 查询数据 + querySql := "select host_id as 'str' from ne_host " + whereSql + " limit 1" + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err %v", err) + return "" + } + if len(results) > 0 { + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" + } + return "" +} + +// Insert 新增信息 +func (r *NeHostImpl) Insert(neHost model.NeHost) string { + // 参数拼接 + params := make(map[string]any) + if neHost.HostType != "" { + params["host_type"] = neHost.HostType + } + if neHost.GroupID != "" { + params["group_id"] = neHost.GroupID + } + if neHost.Title != "" { + params["title"] = neHost.Title + } + if neHost.Addr != "" { + params["addr"] = neHost.Addr + } + if neHost.Port > 0 { + params["port"] = neHost.Port + } + if neHost.User != "" { + params["user"] = neHost.User + } + if neHost.AuthMode != "" { + params["auth_mode"] = neHost.AuthMode + } + if neHost.Password != "" { + passwordEn, err := crypto.StringEncryptByAES(neHost.Password) + if err != nil { + logger.Errorf("insert StringEncryptByAES : %v", err.Error()) + return "" + } + params["password"] = passwordEn + } + if neHost.PrivateKey != "" { + privateKeyEn, err := crypto.StringEncryptByAES(neHost.PrivateKey) + if err != nil { + logger.Errorf("insert StringEncryptByAES : %v", err.Error()) + return "" + } + params["private_key"] = privateKeyEn + } + if neHost.PassPhrase != "" { + passPhraseEn, err := crypto.StringEncryptByAES(neHost.PassPhrase) + if err != nil { + logger.Errorf("insert StringEncryptByAES : %v", err.Error()) + return "" + } + params["pass_phrase"] = passPhraseEn + } + if neHost.Remark != "" { + params["remark"] = neHost.Remark + } + if neHost.CreateBy != "" { + params["create_by"] = neHost.CreateBy + params["create_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params) + sql := "insert into ne_host (" + 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 *NeHostImpl) Update(neHost model.NeHost) int64 { + // 参数拼接 + params := make(map[string]any) + if neHost.HostType != "" { + params["host_type"] = neHost.HostType + } + if neHost.GroupID != "" { + params["group_id"] = neHost.GroupID + } + if neHost.Title != "" { + params["title"] = neHost.Title + } + if neHost.Addr != "" { + params["addr"] = neHost.Addr + } + if neHost.Port > 0 { + params["port"] = neHost.Port + } + if neHost.User != "" { + params["user"] = neHost.User + } + if neHost.AuthMode != "" { + params["auth_mode"] = neHost.AuthMode + } + if neHost.Password != "" { + passwordEn, err := crypto.StringEncryptByAES(neHost.Password) + if err != nil { + logger.Errorf("update StringEncryptByAES : %v", err.Error()) + return 0 + } + params["password"] = passwordEn + } + if neHost.PrivateKey != "" { + privateKeyEn, err := crypto.StringEncryptByAES(neHost.PrivateKey) + if err != nil { + logger.Errorf("update StringEncryptByAES : %v", err.Error()) + return 0 + } + params["private_key"] = privateKeyEn + } + if neHost.PassPhrase != "" { + passPhraseEn, err := crypto.StringEncryptByAES(neHost.PassPhrase) + if err != nil { + logger.Errorf("update StringEncryptByAES : %v", err.Error()) + return 0 + } + params["pass_phrase"] = passPhraseEn + } + params["remark"] = neHost.Remark + if neHost.UpdateBy != "" { + params["update_by"] = neHost.UpdateBy + params["update_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, values := repo.KeyValueByUpdate(params) + sql := "update ne_host set " + strings.Join(keys, ",") + " where host_id = ?" + + // 执行更新 + values = append(values, neHost.HostID) + rows, err := datasource.ExecDB("", sql, values) + if err != nil { + logger.Errorf("update row : %v", err.Error()) + return 0 + } + return rows +} + +// DeleteByIds 批量删除网元主机连接信息 +func (r *NeHostImpl) DeleteByIds(hostIds []string) int64 { + placeholder := repo.KeyPlaceholderByQuery(len(hostIds)) + sql := "delete from ne_host where host_id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(hostIds) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + logger.Errorf("delete err => %v", err) + return 0 + } + return results +} diff --git a/src/modules/network_element/service/ne_host.go b/src/modules/network_element/service/ne_host.go new file mode 100644 index 00000000..483c022b --- /dev/null +++ b/src/modules/network_element/service/ne_host.go @@ -0,0 +1,30 @@ +package service + +import "ems.agt/src/modules/network_element/model" + +// INeHost 网元主机连接 服务层接口 +type INeHost interface { + // SelectPage 根据条件分页查询字典类型 + SelectPage(query map[string]any) map[string]any + + // SelectList 根据实体查询 + SelectList(neHost model.NeHost) []model.NeHost + + // SelectByIds 通过ID查询 + SelectById(hostId string) model.NeHost + + // CheckUniqueHostTitle 校验分组组和主机名称是否唯一 + CheckUniqueHostTitle(groupId, title, hostType, hostId string) bool + + // Insert 新增信息 + Insert(neHost model.NeHost) string + + // Update 修改信息 + Update(neHost model.NeHost) int64 + + // Insert 批量添加 + Inserts(neHosts []model.NeHost) int64 + + // DeleteByIds 批量删除网元主机连接信息 + DeleteByIds(hostIds []string) (int64, error) +} diff --git a/src/modules/network_element/service/ne_host.impl.go b/src/modules/network_element/service/ne_host.impl.go new file mode 100644 index 00000000..58c8b031 --- /dev/null +++ b/src/modules/network_element/service/ne_host.impl.go @@ -0,0 +1,92 @@ +package service + +import ( + "fmt" + + "ems.agt/src/modules/network_element/model" + "ems.agt/src/modules/network_element/repository" +) + +// 实例化服务层 NeHostImpl 结构体 +var NewNeHostImpl = &NeHostImpl{ + neHostRepository: repository.NewNeHostImpl, +} + +// NeHostImpl 网元主机连接 服务层处理 +type NeHostImpl struct { + // 网元主机连接表 + neHostRepository repository.INeHost +} + +// SelectNeHostPage 分页查询列表数据 +func (r *NeHostImpl) SelectPage(query map[string]any) map[string]any { + return r.neHostRepository.SelectPage(query) +} + +// SelectConfigList 查询列表 +func (r *NeHostImpl) SelectList(neHost model.NeHost) []model.NeHost { + return r.neHostRepository.SelectList(neHost) +} + +// SelectByIds 通过ID查询 +func (r *NeHostImpl) SelectById(hostId string) model.NeHost { + if hostId == "" { + return model.NeHost{} + } + neHosts := r.neHostRepository.SelectByIds([]string{hostId}) + if len(neHosts) > 0 { + return neHosts[0] + } + return model.NeHost{} +} + +// Insert 批量添加 +func (r *NeHostImpl) Inserts(neHosts []model.NeHost) int64 { + var num int64 = 0 + for _, v := range neHosts { + hostId := r.neHostRepository.Insert(v) + if hostId != "" { + num += 1 + } + } + return num +} + +// Insert 新增信息 +func (r *NeHostImpl) Insert(neHost model.NeHost) string { + return r.neHostRepository.Insert(neHost) +} + +// Update 修改信息 +func (r *NeHostImpl) Update(neHost model.NeHost) int64 { + return r.neHostRepository.Update(neHost) +} + +// DeleteByIds 批量删除网元主机连接信息 +func (r *NeHostImpl) DeleteByIds(hostIds []string) (int64, error) { + // 检查是否存在 + ids := r.neHostRepository.SelectByIds(hostIds) + if len(ids) <= 0 { + return 0, fmt.Errorf("neHost.noData") + } + + if len(ids) == len(hostIds) { + rows := r.neHostRepository.DeleteByIds(hostIds) + return rows, nil + } + // 删除参数配置信息失败! + return 0, fmt.Errorf("neHost.errDelete") +} + +// CheckUniqueHostTitle 校验分组组和主机名称是否唯一 +func (r *NeHostImpl) CheckUniqueHostTitle(groupId, title, hostType, hostId string) bool { + uniqueId := r.neHostRepository.CheckUniqueNeHost(model.NeHost{ + HostType: hostType, + GroupID: groupId, + Title: title, + }) + if uniqueId == hostId { + return true + } + return uniqueId == "" +}