feat: 用户导入角色初始/网元文件列表
This commit is contained in:
@@ -58,7 +58,7 @@ redis:
|
|||||||
# UDM网元用户库
|
# UDM网元用户库
|
||||||
udmuser:
|
udmuser:
|
||||||
port: 6379 # Redis port
|
port: 6379 # Redis port
|
||||||
host: "192.168.1.187"
|
host: "192.168.5.57"
|
||||||
password: ""
|
password: ""
|
||||||
db: 0 # Redis db_num
|
db: 0 # Redis db_num
|
||||||
# 多个数据源时可以用这个指定默认的数据源
|
# 多个数据源时可以用这个指定默认的数据源
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1,19 +1,19 @@
|
|||||||
# 项目信息
|
# 项目信息
|
||||||
framework:
|
framework:
|
||||||
name: "ems_agt"
|
name: "CN EMS"
|
||||||
version: "0.0.1"
|
version: "2.2312.9"
|
||||||
|
|
||||||
# 应用服务配置
|
# 应用服务配置
|
||||||
server:
|
server:
|
||||||
# 服务端口
|
# 服务端口
|
||||||
port: 3040
|
port: 3030
|
||||||
# 是否开启代理
|
# 是否开启代理
|
||||||
proxy: false
|
proxy: false
|
||||||
|
|
||||||
# 日志
|
# 日志
|
||||||
logger:
|
logger:
|
||||||
fileDir: "/usr/local/omc/log"
|
fileDir: "/var/log"
|
||||||
fileName: "ems_agt.log"
|
fileName: "omc.log"
|
||||||
level: 2 # 日志记录的等级 0:silent<1:info<2:warn<3:error
|
level: 2 # 日志记录的等级 0:silent<1:info<2:warn<3:error
|
||||||
maxDay: 180 # 日志会保留 180 天
|
maxDay: 180 # 日志会保留 180 天
|
||||||
maxSize: 10 # 调整按 10MB 大小的切割
|
maxSize: 10 # 调整按 10MB 大小的切割
|
||||||
|
|||||||
104
src/framework/utils/ssh/files.go
Normal file
104
src/framework/utils/ssh/files.go
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
package ssh
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"ems.agt/src/framework/cmd"
|
||||||
|
"ems.agt/src/framework/config"
|
||||||
|
"ems.agt/src/framework/logger"
|
||||||
|
"ems.agt/src/framework/utils/parse"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FileListRow 文件列表行数据
|
||||||
|
type FileListRow struct {
|
||||||
|
FileType string `json:"fileType"` // 文件类型
|
||||||
|
FileMode string `json:"fileMode"` // 文件的权限
|
||||||
|
LinkCount int64 `json:"linkCount"` // 硬链接数目
|
||||||
|
Owner string `json:"owner"` // 所属用户
|
||||||
|
Group string `json:"group"` // 所属组
|
||||||
|
Size string `json:"size"` // 文件的大小
|
||||||
|
ModifiedTime int64 `json:"modifiedTime"` // 最后修改时间,单位为秒
|
||||||
|
FileName string `json:"fileName"` // 文件的名称
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件列表
|
||||||
|
// neIp 网元IP空字符串为本地
|
||||||
|
// search 文件名后模糊*
|
||||||
|
//
|
||||||
|
// return 目录大小,行记录,异常
|
||||||
|
func FileList(path, neIp, search string) (string, []FileListRow, error) {
|
||||||
|
totalSize := ""
|
||||||
|
var rows []FileListRow
|
||||||
|
rowStr := ""
|
||||||
|
|
||||||
|
// 发送命令
|
||||||
|
searchStr := ""
|
||||||
|
if search != "" {
|
||||||
|
searchStr = search + "*"
|
||||||
|
}
|
||||||
|
pathStr := fmt.Sprintf("cd %s \n", path)
|
||||||
|
cmdStr := fmt.Sprintf("ls -lht --time-style=+%%s %s \n", searchStr)
|
||||||
|
|
||||||
|
// 是否远程读取
|
||||||
|
if neIp != "" {
|
||||||
|
usernameNe := config.Get("ne.user").(string) // 网元统一用户
|
||||||
|
sshHost := fmt.Sprintf("%s@%s", usernameNe, neIp)
|
||||||
|
resultStr, err := cmd.ExecWithCheck("ssh", sshHost, pathStr, cmdStr)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Ne FileList Path: %s, Search: %s, Error:%s", path, search, err.Error())
|
||||||
|
return totalSize, rows, err
|
||||||
|
}
|
||||||
|
rowStr = resultStr
|
||||||
|
} else {
|
||||||
|
resultStr, err := cmd.Execf(pathStr, cmdStr)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Ne FileList Path: %s, Search: %s, Error:%s", path, search, err.Error())
|
||||||
|
return totalSize, rows, err
|
||||||
|
}
|
||||||
|
rowStr = resultStr
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历组装
|
||||||
|
rowStrList := strings.Split(rowStr, "\n")
|
||||||
|
for i, rowStr := range rowStrList {
|
||||||
|
if rowStr == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 使用空格对字符串进行切割
|
||||||
|
fields := strings.Fields(rowStr)
|
||||||
|
|
||||||
|
// 无查询过滤会有total总计
|
||||||
|
if i == 0 && searchStr == "" {
|
||||||
|
totalSize = fields[1]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拆分不足7位跳过
|
||||||
|
if len(fields) != 7 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件类型
|
||||||
|
fileMode := fields[0]
|
||||||
|
fileType := "file"
|
||||||
|
if fileMode[0] == 'd' {
|
||||||
|
fileType = "dir"
|
||||||
|
} else if fileMode[0] == 'l' {
|
||||||
|
fileType = "symlink"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取各个字段的值
|
||||||
|
rows = append(rows, FileListRow{
|
||||||
|
FileMode: fileMode,
|
||||||
|
FileType: fileType,
|
||||||
|
LinkCount: parse.Number(fields[1]),
|
||||||
|
Owner: fields[2],
|
||||||
|
Group: fields[3],
|
||||||
|
Size: fields[4],
|
||||||
|
ModifiedTime: parse.Number(fields[5]),
|
||||||
|
FileName: fields[6],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return totalSize, rows, nil
|
||||||
|
}
|
||||||
@@ -6,44 +6,39 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"ems.agt/lib/core/conf"
|
"ems.agt/src/framework/config"
|
||||||
"ems.agt/lib/log"
|
"ems.agt/src/framework/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 网元NE 文件复制到远程文件
|
// 网元NE 文件复制到远程文件
|
||||||
func FileSCPLocalToNe(neIp, localPath, nePath string) error {
|
func FileSCPLocalToNe(neIp, localPath, nePath string) error {
|
||||||
usernameNe := conf.Get("ne.user").(string)
|
usernameNe := config.Get("ne.user").(string)
|
||||||
// scp /path/to/local/file.txt user@remote-server:/path/to/remote/directory/
|
// scp /path/to/local/file.txt user@remote-server:/path/to/remote/directory/
|
||||||
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
|
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
|
||||||
cmd := exec.Command("scp", "-r", localPath, neDir)
|
cmd := exec.Command("scp", "-r", localPath, neDir)
|
||||||
out, err := cmd.CombinedOutput()
|
_, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Errorf("FileSCPLocalToNe %s", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Infof("FileSCPLocalToNe %s", string(out))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 网元NE 远程文件复制到本地文件
|
// 网元NE 远程文件复制到本地文件
|
||||||
func FileSCPNeToLocal(neIp, nePath, localPath string) error {
|
func FileSCPNeToLocal(neIp, nePath, localPath string) error {
|
||||||
// 获取文件所在的目录路径
|
|
||||||
dirPath := filepath.Dir(localPath)
|
|
||||||
|
|
||||||
// 确保文件夹路径存在
|
// 确保文件夹路径存在
|
||||||
err := os.MkdirAll(dirPath, os.ModePerm)
|
if err := os.MkdirAll(filepath.Dir(localPath), 0750); err != nil {
|
||||||
if err != nil {
|
logger.Errorf("FileSCPNeToLocal MkdirAll err %v", err)
|
||||||
log.Errorf("FileSCPNeToLocal MkdirAll err %v", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
usernameNe := config.Get("ne.user").(string)
|
||||||
usernameNe := conf.Get("ne.user").(string)
|
|
||||||
// scp user@remote-server:/path/to/remote/directory/ /path/to/local/file.txt
|
// scp user@remote-server:/path/to/remote/directory/ /path/to/local/file.txt
|
||||||
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
|
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
|
||||||
cmd := exec.Command("scp", "-r", neDir, localPath)
|
cmd := exec.Command("scp", "-r", neDir, localPath)
|
||||||
out, err := cmd.CombinedOutput()
|
_, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Errorf("FileSCPNeToLocal %s", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Infof("FileSCPNeToLocal %s", string(out))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package common
|
|||||||
import (
|
import (
|
||||||
"ems.agt/src/framework/logger"
|
"ems.agt/src/framework/logger"
|
||||||
"ems.agt/src/framework/middleware"
|
"ems.agt/src/framework/middleware"
|
||||||
"ems.agt/src/framework/middleware/collectlogs"
|
|
||||||
"ems.agt/src/modules/common/controller"
|
"ems.agt/src/modules/common/controller"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -26,12 +25,6 @@ func Setup(router *gin.Engine) {
|
|||||||
|
|
||||||
// 系统可暴露的配置信息
|
// 系统可暴露的配置信息
|
||||||
indexGroup.GET("/sys-conf", controller.NewCommont.SysConfig)
|
indexGroup.GET("/sys-conf", controller.NewCommont.SysConfig)
|
||||||
// 转存上传文件到静态资源
|
|
||||||
indexGroup.POST("/transferStaticFile",
|
|
||||||
middleware.PreAuthorize(nil),
|
|
||||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.helpDoc", collectlogs.BUSINESS_TYPE_UPDATE)),
|
|
||||||
controller.NewCommont.TransferStaticFile,
|
|
||||||
)
|
|
||||||
|
|
||||||
// 验证码操作处理
|
// 验证码操作处理
|
||||||
indexGroup.GET("/captchaImage",
|
indexGroup.GET("/captchaImage",
|
||||||
@@ -92,5 +85,6 @@ func Setup(router *gin.Engine) {
|
|||||||
fileGroup.POST("/chunkCheck", middleware.PreAuthorize(nil), controller.NewFile.ChunkCheck)
|
fileGroup.POST("/chunkCheck", middleware.PreAuthorize(nil), controller.NewFile.ChunkCheck)
|
||||||
fileGroup.POST("/chunkUpload", middleware.PreAuthorize(nil), controller.NewFile.ChunkUpload)
|
fileGroup.POST("/chunkUpload", middleware.PreAuthorize(nil), controller.NewFile.ChunkUpload)
|
||||||
fileGroup.POST("/chunkMerge", middleware.PreAuthorize(nil), controller.NewFile.ChunkMerge)
|
fileGroup.POST("/chunkMerge", middleware.PreAuthorize(nil), controller.NewFile.ChunkMerge)
|
||||||
|
fileGroup.POST("/transferStaticFile", middleware.PreAuthorize(nil), controller.NewCommont.TransferStaticFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"ems.agt/src/framework/config"
|
|
||||||
"ems.agt/src/framework/i18n"
|
"ems.agt/src/framework/i18n"
|
||||||
"ems.agt/src/framework/utils/ctx"
|
"ems.agt/src/framework/utils/ctx"
|
||||||
"ems.agt/src/framework/utils/file"
|
|
||||||
"ems.agt/src/framework/vo/result"
|
"ems.agt/src/framework/vo/result"
|
||||||
commonService "ems.agt/src/modules/common/service"
|
commonService "ems.agt/src/modules/common/service"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gin-gonic/gin/binding"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 实例化控制层 CommontController 结构体
|
// 实例化控制层 CommontController 结构体
|
||||||
@@ -76,43 +69,3 @@ func (s *CommontController) SysConfig(c *gin.Context) {
|
|||||||
|
|
||||||
c.JSON(200, result.OkData(data))
|
c.JSON(200, result.OkData(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转存指定对应文件
|
|
||||||
//
|
|
||||||
// POST /transferStaticFile
|
|
||||||
func (s *CommontController) TransferStaticFile(c *gin.Context) {
|
|
||||||
language := ctx.AcceptLanguage(c)
|
|
||||||
var body struct {
|
|
||||||
UploadPath string `json:"uploadPath" binding:"required"`
|
|
||||||
StaticPath string `json:"staticPath" binding:"required"`
|
|
||||||
Language string `json:"language" binding:"required"`
|
|
||||||
}
|
|
||||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
|
||||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 取语言前缀
|
|
||||||
lang := strings.SplitN(body.Language, "_", 2)[0]
|
|
||||||
|
|
||||||
// 默认静态资源
|
|
||||||
static := config.Get("staticFile.default").(map[string]any)
|
|
||||||
dir, err := filepath.Abs(static["dir"].(string))
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(400, result.CodeMsg(400, err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
delPrefix := strings.Replace(body.StaticPath, static["prefix"].(string), "", 1)
|
|
||||||
staticPath := strings.Replace(delPrefix, "{language}", lang, 1)
|
|
||||||
newFile := fmt.Sprintf("%s%s", dir, staticPath)
|
|
||||||
|
|
||||||
err = file.CopyUploadFile(body.UploadPath, newFile)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(400, result.CodeMsg(400, err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
urlPath := strings.Replace(newFile, dir, static["prefix"].(string), 1)
|
|
||||||
c.JSON(200, result.OkData(filepath.ToSlash(urlPath)))
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"ems.agt/src/framework/config"
|
||||||
"ems.agt/src/framework/constants/uploadsubpath"
|
"ems.agt/src/framework/constants/uploadsubpath"
|
||||||
"ems.agt/src/framework/i18n"
|
"ems.agt/src/framework/i18n"
|
||||||
"ems.agt/src/framework/utils/ctx"
|
"ems.agt/src/framework/utils/ctx"
|
||||||
@@ -13,6 +15,7 @@ import (
|
|||||||
"ems.agt/src/framework/vo/result"
|
"ems.agt/src/framework/vo/result"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gin-gonic/gin/binding"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 实例化控制层 FileController 结构体
|
// 实例化控制层 FileController 结构体
|
||||||
@@ -190,3 +193,43 @@ func (s *FileController) ChunkUpload(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
c.JSON(206, result.OkData(chunkFilePath))
|
c.JSON(206, result.OkData(chunkFilePath))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 转存指定对应文件到静态目录
|
||||||
|
//
|
||||||
|
// POST /transferStaticFile
|
||||||
|
func (s *CommontController) TransferStaticFile(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
var body struct {
|
||||||
|
UploadPath string `json:"uploadPath" binding:"required"`
|
||||||
|
StaticPath string `json:"staticPath" binding:"required"`
|
||||||
|
Language string `json:"language" binding:"required"`
|
||||||
|
}
|
||||||
|
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取语言前缀
|
||||||
|
lang := strings.SplitN(body.Language, "_", 2)[0]
|
||||||
|
|
||||||
|
// 默认静态资源
|
||||||
|
static := config.Get("staticFile.default").(map[string]any)
|
||||||
|
dir, err := filepath.Abs(static["dir"].(string))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
delPrefix := strings.Replace(body.StaticPath, static["prefix"].(string), "", 1)
|
||||||
|
staticPath := strings.Replace(delPrefix, "{language}", lang, 1)
|
||||||
|
newFile := fmt.Sprintf("%s%s", dir, staticPath)
|
||||||
|
|
||||||
|
err = file.CopyUploadFile(body.UploadPath, newFile)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
urlPath := strings.Replace(newFile, dir, static["prefix"].(string), 1)
|
||||||
|
c.JSON(200, result.OkData(filepath.ToSlash(urlPath)))
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,3 +66,93 @@ func (s *NeActionController) PushFile(c *gin.Context) {
|
|||||||
neFilePath := fmt.Sprintf("%s/%s", nePath, fileName)
|
neFilePath := fmt.Sprintf("%s/%s", nePath, fileName)
|
||||||
c.JSON(200, result.OkData(filepath.ToSlash(neFilePath)))
|
c.JSON(200, result.OkData(filepath.ToSlash(neFilePath)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从网元端获取文件
|
||||||
|
//
|
||||||
|
// GET /pullFile
|
||||||
|
func (s *NeActionController) PullFile(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
var querys struct {
|
||||||
|
NeType string `form:"neType" binding:"required"`
|
||||||
|
NeID string `form:"neId" binding:"required"`
|
||||||
|
Path string `form:"path" binding:"required"`
|
||||||
|
FileName string `form:"fileName" 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
|
||||||
|
}
|
||||||
|
|
||||||
|
nePath := fmt.Sprintf("%s/%s", querys.Path, querys.FileName)
|
||||||
|
localPath := fmt.Sprintf("/tmp/omc/pullFile/%s", querys.FileName)
|
||||||
|
err := ssh.FileSCPNeToLocal(neInfo.IP, nePath, localPath)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.FileAttachment(localPath, querys.FileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 网元端文件列表
|
||||||
|
//
|
||||||
|
// GET /files
|
||||||
|
func (s *NeActionController) Files(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
var querys struct {
|
||||||
|
NeType string `form:"neType" binding:"required"`
|
||||||
|
NeID string `form:"neId" binding:"required"`
|
||||||
|
Path string `form:"path" binding:"required"`
|
||||||
|
PageNum int64 `form:"pageNum" binding:"required"`
|
||||||
|
PageSize int64 `form:"pageSize" binding:"required"`
|
||||||
|
Search string `form:"search"`
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
totalSize, rows, err := ssh.FileList(querys.Path, neInfo.IP, querys.Search)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.Ok(map[string]any{
|
||||||
|
"path": querys.Path,
|
||||||
|
"totalSize": totalSize,
|
||||||
|
"total": len(rows),
|
||||||
|
"rows": []ssh.FileListRow{},
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对数组进行切片分页
|
||||||
|
lenNum := int64(len(rows))
|
||||||
|
start := (querys.PageNum - 1) * querys.PageSize
|
||||||
|
end := start + querys.PageSize
|
||||||
|
var splitRows []ssh.FileListRow
|
||||||
|
if start >= lenNum {
|
||||||
|
splitRows = []ssh.FileListRow{}
|
||||||
|
} else if end >= lenNum {
|
||||||
|
splitRows = rows[start:]
|
||||||
|
} else {
|
||||||
|
splitRows = rows[start:end]
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, result.Ok(map[string]any{
|
||||||
|
"path": querys.Path,
|
||||||
|
"totalSize": totalSize,
|
||||||
|
"total": lenNum,
|
||||||
|
"rows": splitRows,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,7 +25,14 @@ func Setup(router *gin.Engine) {
|
|||||||
// 网元处理
|
// 网元处理
|
||||||
neActionGroup := neGroup.Group("/action")
|
neActionGroup := neGroup.Group("/action")
|
||||||
{
|
{
|
||||||
// 发送文件到网元服务器
|
neActionGroup.GET("/files",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
controller.NewNeAction.Files,
|
||||||
|
)
|
||||||
|
neActionGroup.GET("/pullFile",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
controller.NewNeAction.PullFile,
|
||||||
|
)
|
||||||
neActionGroup.POST("/pushFile",
|
neActionGroup.POST("/pushFile",
|
||||||
middleware.PreAuthorize(nil),
|
middleware.PreAuthorize(nil),
|
||||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neAction", collectlogs.BUSINESS_TYPE_IMPORT)),
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neAction", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||||
|
|||||||
@@ -507,11 +507,12 @@ func (s *SysUserController) Export(c *gin.Context) {
|
|||||||
"E1": i18n.TKey(language, "user.export.phone"),
|
"E1": i18n.TKey(language, "user.export.phone"),
|
||||||
"F1": i18n.TKey(language, "user.export.sex"),
|
"F1": i18n.TKey(language, "user.export.sex"),
|
||||||
"G1": i18n.TKey(language, "user.export.status"),
|
"G1": i18n.TKey(language, "user.export.status"),
|
||||||
"H1": i18n.TKey(language, "user.export.deptID"),
|
"H1": i18n.TKey(language, "user.export.role"),
|
||||||
"I1": i18n.TKey(language, "user.export.deptName"),
|
"I1": i18n.TKey(language, "user.export.deptID"),
|
||||||
"J1": i18n.TKey(language, "user.export.deptLeader"),
|
"J1": i18n.TKey(language, "user.export.deptName"),
|
||||||
"K1": i18n.TKey(language, "user.export.loginIP"),
|
"K1": i18n.TKey(language, "user.export.deptLeader"),
|
||||||
"L1": i18n.TKey(language, "user.export.loginDate"),
|
"L1": i18n.TKey(language, "user.export.loginIP"),
|
||||||
|
"M1": i18n.TKey(language, "user.export.loginDate"),
|
||||||
}
|
}
|
||||||
// 读取用户性别字典数据
|
// 读取用户性别字典数据
|
||||||
dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex")
|
dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex")
|
||||||
@@ -532,6 +533,13 @@ func (s *SysUserController) Export(c *gin.Context) {
|
|||||||
if row.Status == "1" {
|
if row.Status == "1" {
|
||||||
statusValue = i18n.TKey(language, "dictData.normal")
|
statusValue = i18n.TKey(language, "dictData.normal")
|
||||||
}
|
}
|
||||||
|
// 用户角色, 默认导出首个
|
||||||
|
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)
|
||||||
|
}
|
||||||
dataCells = append(dataCells, map[string]any{
|
dataCells = append(dataCells, map[string]any{
|
||||||
"A" + idx: row.UserID,
|
"A" + idx: row.UserID,
|
||||||
"B" + idx: row.UserName,
|
"B" + idx: row.UserName,
|
||||||
@@ -540,11 +548,12 @@ func (s *SysUserController) Export(c *gin.Context) {
|
|||||||
"E" + idx: row.PhoneNumber,
|
"E" + idx: row.PhoneNumber,
|
||||||
"F" + idx: sysUserSex,
|
"F" + idx: sysUserSex,
|
||||||
"G" + idx: statusValue,
|
"G" + idx: statusValue,
|
||||||
"H" + idx: row.Dept.DeptID,
|
"H" + idx: userRole,
|
||||||
"I" + idx: row.Dept.DeptName,
|
"I" + idx: row.Dept.DeptID,
|
||||||
"J" + idx: row.Dept.Leader,
|
"J" + idx: row.Dept.DeptName,
|
||||||
"K" + idx: row.LoginIP,
|
"K" + idx: row.Dept.Leader,
|
||||||
"L" + idx: date.ParseDateToStr(row.LoginDate, date.YYYY_MM_DD_HH_MM_SS),
|
"L" + idx: row.LoginIP,
|
||||||
|
"M" + idx: date.ParseDateToStr(row.LoginDate, date.YYYY_MM_DD_HH_MM_SS),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,22 +664,32 @@ func (s *SysUserController) ImportData(c *gin.Context) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 用户状态
|
||||||
sysUserStatus := common.STATUS_NO
|
sysUserStatus := common.STATUS_NO
|
||||||
if row["G"] == "Normal" {
|
if row["G"] == "正常" || row["G"] == "Normal" {
|
||||||
sysUserStatus = common.STATUS_YES
|
sysUserStatus = common.STATUS_YES
|
||||||
}
|
}
|
||||||
|
// 用户角色 拿编号
|
||||||
|
sysUserRole := ""
|
||||||
|
if v, ok := row["H"]; ok && v != "" {
|
||||||
|
sysUserRole = strings.SplitN(v, "-", 2)[0]
|
||||||
|
if sysUserRole == "1" {
|
||||||
|
sysUserRole = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 构建用户实体信息
|
// 构建用户实体信息
|
||||||
newSysUser := model.SysUser{
|
newSysUser := model.SysUser{
|
||||||
UserType: "sys",
|
UserType: "sys",
|
||||||
Password: initPassword,
|
Password: initPassword,
|
||||||
DeptID: row["H"],
|
DeptID: row["I"],
|
||||||
UserName: row["B"],
|
UserName: row["B"],
|
||||||
NickName: row["C"],
|
NickName: row["C"],
|
||||||
PhoneNumber: row["E"],
|
PhoneNumber: row["E"],
|
||||||
Email: row["D"],
|
Email: row["D"],
|
||||||
Status: sysUserStatus,
|
Status: sysUserStatus,
|
||||||
Sex: sysUserSex,
|
Sex: sysUserSex,
|
||||||
|
RoleIDs: []string{sysUserRole},
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查手机号码格式并判断是否唯一
|
// 检查手机号码格式并判断是否唯一
|
||||||
@@ -725,7 +744,7 @@ func (s *SysUserController) ImportData(c *gin.Context) {
|
|||||||
successMsgArr = append(successMsgArr, msg)
|
successMsgArr = append(successMsgArr, msg)
|
||||||
} else {
|
} else {
|
||||||
// 用户编号:%s 登录名称 %s 导入失败
|
// 用户编号:%s 登录名称 %s 导入失败
|
||||||
msg := i18n.TTemplate(language, "user.import.fail", map[string]any{"id": row["A"], "email": newSysUser.UserName})
|
msg := i18n.TTemplate(language, "user.import.fail", map[string]any{"id": row["A"], "name": newSysUser.UserName})
|
||||||
failureNum++
|
failureNum++
|
||||||
failureMsgArr = append(failureMsgArr, msg)
|
failureMsgArr = append(failureMsgArr, msg)
|
||||||
}
|
}
|
||||||
@@ -739,12 +758,12 @@ func (s *SysUserController) ImportData(c *gin.Context) {
|
|||||||
rows := s.sysUserService.UpdateUser(newSysUser)
|
rows := s.sysUserService.UpdateUser(newSysUser)
|
||||||
if rows > 0 {
|
if rows > 0 {
|
||||||
// 用户编号:%s 登录名称 %s 更新成功
|
// 用户编号:%s 登录名称 %s 更新成功
|
||||||
msg := i18n.TTemplate(language, "user.import.successUpdate", map[string]any{"id": row["A"], "email": newSysUser.UserName})
|
msg := i18n.TTemplate(language, "user.import.successUpdate", map[string]any{"id": row["A"], "name": newSysUser.UserName})
|
||||||
successNum++
|
successNum++
|
||||||
successMsgArr = append(successMsgArr, msg)
|
successMsgArr = append(successMsgArr, msg)
|
||||||
} else {
|
} else {
|
||||||
// 用户编号:%s 登录名称 %s 更新失败
|
// 用户编号:%s 登录名称 %s 更新失败
|
||||||
msg := i18n.TTemplate(language, "user.import.failUpdate", map[string]any{"id": row["A"], "email": newSysUser.UserName})
|
msg := i18n.TTemplate(language, "user.import.failUpdate", map[string]any{"id": row["A"], "name": newSysUser.UserName})
|
||||||
failureNum++
|
failureNum++
|
||||||
failureMsgArr = append(failureMsgArr, msg)
|
failureMsgArr = append(failureMsgArr, msg)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ func (s *TcpdumpController) Download(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nePath := fmt.Sprintf("/tmp/%s", body.FileName)
|
nePath := fmt.Sprintf("/tmp/%s", body.FileName)
|
||||||
localPath := fmt.Sprintf("%s/tcpdump/%s", config.Get("ne.scpdir"), body.FileName)
|
localPath := fmt.Sprintf("/tmp/omc/tcpdump/%s", body.FileName)
|
||||||
err = ssh.FileSCPNeToLocal(neInfo.IP, nePath, localPath)
|
err = ssh.FileSCPNeToLocal(neInfo.IP, nePath, localPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(200, result.ErrMsg(err.Error()))
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
|||||||
Reference in New Issue
Block a user