From 96241ef281e286ab874c4fd8c3854e6d14974456 Mon Sep 17 00:00:00 2001 From: zhangsz Date: Tue, 1 Apr 2025 16:20:26 +0800 Subject: [PATCH] feat: support export ue data --- features/features.go | 2 + features/ue/file_export/controller.go | 136 ++++++++++++++++++ features/ue/file_export/model.go | 30 ++++ features/ue/file_export/route.go | 39 +++++ features/ue/service.go | 17 +++ .../processor/exportUEData/exportUEData.go | 1 + 6 files changed, 225 insertions(+) create mode 100644 features/ue/file_export/controller.go create mode 100644 features/ue/file_export/model.go create mode 100644 features/ue/file_export/route.go create mode 100644 features/ue/service.go diff --git a/features/features.go b/features/features.go index e4f68c75..49c5eb70 100644 --- a/features/features.go +++ b/features/features.go @@ -5,6 +5,7 @@ import ( "be.ems/features/lm" "be.ems/features/nbi" "be.ems/features/pm" + "be.ems/features/ue" "be.ems/lib/log" "github.com/gin-gonic/gin" ) @@ -18,5 +19,6 @@ func InitServiceEngine(r *gin.Engine) { lm.InitSubServiceRoute(r) cm.InitSubServiceRoute(r) nbi.InitSubServiceRoute(r) + ue.InitSubServiceRoute(r) // return featuresGroup } diff --git a/features/ue/file_export/controller.go b/features/ue/file_export/controller.go new file mode 100644 index 00000000..f40d93e0 --- /dev/null +++ b/features/ue/file_export/controller.go @@ -0,0 +1,136 @@ +package file_export + +import ( + "encoding/json" + "net/http" + "os" + "path/filepath" + + "be.ems/lib/file" + "be.ems/lib/log" + "be.ems/lib/services" + "be.ems/src/framework/datasource" + "be.ems/src/framework/i18n" + "be.ems/src/framework/utils/ctx" + "be.ems/src/modules/crontask/processor/exportUEData" + "github.com/gin-gonic/gin" +) + +type SysJobResponse struct { + SysJob + TableName string `json:"tableName"` + TableDisplay string `json:"tableDisplay"` + FilePath string `json:"filePath"` +} + +// GetFileExportTable 获取文件导出任务列表 +func (m *SysJob) GetFileExportTable(c *gin.Context) { + var results []SysJob + + err := datasource.DefaultDB().Table(m.TableName()).Where("invoke_target=? and status=1", INVOKE_FILE_EXPORT). + Find(&results).Error + if err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + language := ctx.AcceptLanguage(c) + var response []SysJobResponse + for _, job := range results { + params := make([]exportUEData.BarParams, 0) + if err := json.Unmarshal([]byte(job.TargetParams), ¶ms); err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + for _, param := range params { + TableDisplay := i18n.TKey(language, "table."+param.TableName) + if TableDisplay == "" { + TableDisplay = param.TableName + } + response = append(response, SysJobResponse{ + SysJob: job, + TableName: param.TableName, + TableDisplay: TableDisplay, + FilePath: param.FilePath, + }) + } + } + c.JSON(http.StatusOK, services.DataResp(response)) +} + +func (m *FileExport) GetFileList(c *gin.Context) { + var querys FileExportQuery + + if err := c.ShouldBindQuery(&querys); err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + + files, err := file.GetFileInfo(querys.Path, querys.Suffix) + if err != nil { + log.Error("failed to GetFileInfo:", err) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + + // split files list + lenNum := int64(len(files)) + start := (querys.PageNum - 1) * querys.PageSize + end := start + querys.PageSize + var splitList []file.FileInfo + if start >= lenNum { + splitList = []file.FileInfo{} + } else if end >= lenNum { + splitList = files[start:] + } else { + splitList = files[start:end] + } + total := len(files) + c.JSON(http.StatusOK, services.TotalDataResp(splitList, total)) +} + +func (m *FileExport) Total(c *gin.Context) { + dir := c.Query("path") + + fileCount, dirCount, err := file.GetFileAndDirCount(dir) + if err != nil { + log.Error("failed to GetFileAndDirCount:", err) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + total := fileCount + dirCount + c.JSON(http.StatusOK, services.TotalResp(int64(total))) +} + +func (m *FileExport) DownloadHandler(c *gin.Context) { + dir := c.Query("path") + fileName := c.Param("fileName") + filePath := filepath.Join(dir, fileName) + + file, err := os.Open(filePath) + if err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + defer file.Close() + + if _, err := os.Stat(filePath); os.IsNotExist(err) { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + + c.Header("Content-Disposition", "attachment; filename="+fileName) + c.Header("Content-Type", "application/octet-stream") + c.File(filePath) +} + +func (m *FileExport) Delete(c *gin.Context) { + fileName := c.Param("fileName") + dir := c.Query("path") + filePath := filepath.Join(dir, fileName) + + if err := os.Remove(filePath); err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + c.JSON(http.StatusNoContent, nil) // 204 No Content +} diff --git a/features/ue/file_export/model.go b/features/ue/file_export/model.go new file mode 100644 index 00000000..3c849d53 --- /dev/null +++ b/features/ue/file_export/model.go @@ -0,0 +1,30 @@ +package file_export + +import ( + "be.ems/lib/file" +) + +const ( + INVOKE_FILE_EXPORT = "exportUEData" // 调用目标字符串 +) + +type SysJob struct { + JobID int64 `gorm:"column:job_id;primary_key;auto_increment" json:"job_id"` //任务ID + InvokeTarget string `gorm:"column:invoke_target" json:"invoke_target"` //调用目标字符串 + TargetParams string `gorm:"column:target_params;type:json" json:"target_params,omitempty"` //调用目标传入参数 +} + +func (m *SysJob) TableName() string { + return "sys_job" +} + +type FileExport struct { + file.FileInfo +} + +type FileExportQuery struct { + Path string `form:"path" binding:"required"` + Suffix string `form:"suffix"` + PageNum int64 `form:"pageNum" binding:"required"` + PageSize int64 `form:"pageSize" binding:"required"` +} diff --git a/features/ue/file_export/route.go b/features/ue/file_export/route.go new file mode 100644 index 00000000..887b7cc2 --- /dev/null +++ b/features/ue/file_export/route.go @@ -0,0 +1,39 @@ +package file_export + +import ( + "be.ems/src/framework/middleware" + "github.com/gin-gonic/gin" +) + +// Register Routes for file_export +func Register(r *gin.RouterGroup) { + + ueTable := r.Group("/table") + { + var m *SysJob + ueTable.GET("/list", + middleware.PreAuthorize(nil), + m.GetFileExportTable, + ) + } + ueFile := r.Group("/file") + { + var f *FileExport + ueFile.GET("/list", + middleware.PreAuthorize(nil), + f.GetFileList, + ) + ueFile.GET("/total", + middleware.PreAuthorize(nil), + f.Total, + ) + ueFile.GET("/:fileName", + middleware.PreAuthorize(nil), + f.DownloadHandler, + ) + ueFile.DELETE("/:fileName", + middleware.PreAuthorize(nil), + f.Delete, + ) + } +} diff --git a/features/ue/service.go b/features/ue/service.go new file mode 100644 index 00000000..014fdc4d --- /dev/null +++ b/features/ue/service.go @@ -0,0 +1,17 @@ +// log management package + +package ue + +import ( + "be.ems/features/ue/file_export" + "be.ems/lib/log" + "github.com/gin-gonic/gin" +) + +func InitSubServiceRoute(r *gin.Engine) { + log.Info("======init UE management group gin.Engine") + + ueGroup := r.Group("/ue") + // register sub modules routes + file_export.Register(ueGroup) +} diff --git a/src/modules/crontask/processor/exportUEData/exportUEData.go b/src/modules/crontask/processor/exportUEData/exportUEData.go index fa406e07..b4fb1d51 100644 --- a/src/modules/crontask/processor/exportUEData/exportUEData.go +++ b/src/modules/crontask/processor/exportUEData/exportUEData.go @@ -101,6 +101,7 @@ func (s *BarProcessor) exportUEData(param BarParams) (map[string]any, error) { var fps []string var affectedArr []int64 for _, neID := range neIDs { + log.Trace("ne_id:", neID) // 1. 加载最新数据, 如果数据服务存在,则重新加载数据 dataService, err := networkdata.GetService(param.ServiceName) if err != nil {