package nbi_file import ( "archive/zip" "fmt" "io" "net/http" "os" "path/filepath" "time" "be.ems/lib/dborm" "be.ems/lib/file" "be.ems/lib/global" "be.ems/lib/log" "be.ems/lib/services" "github.com/gin-gonic/gin" ) type SysJobResponse struct { SysJob TableName string `json:"tableName"` TableDisplay string `json:"tableDisplay"` FilePath string `json:"filePath"` } type TargetParams struct { Duration int `json:"duration"` TableName string `json:"tableName"` Columns string `json:"columns"` // exported column name of time string TimeCol string `json:"timeCol"` // time stamp of column name TimeUnit string `json:"timeUnit"` // timestamp unit: second/micro/milli Extras string `json:"extras"` // extras condition for where FilePath string `json:"filePath"` // file path } func (m *FileNBI) GetFileList(c *gin.Context) { var querys FileNBIQuery querys.Category = c.Param("category") querys.Type = c.Param("type") if err := c.ShouldBindQuery(&querys); err != nil { c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } if querys.Path == "" { tableName := "" ok := false switch querys.Category { case "cdr": tableName, ok = CDRTableMapper[querys.Type] if tableName == "" || !ok { c.JSON(http.StatusOK, services.ErrResp(fmt.Sprintf("invalid CDR file type: %s", querys.Type))) return } case "log": tableName, ok = LogTableMapper[querys.Type] if tableName == "" || !ok { c.JSON(http.StatusOK, services.ErrResp(fmt.Sprintf("invalid log file type: %s", querys.Type))) return } default: c.JSON(http.StatusOK, services.ErrResp(fmt.Sprintf("invalid log file category: %s", querys.Category))) return } s := SysJob{} where := fmt.Sprintf("invoke_target='%s' and status=1 and JSON_UNQUOTE(JSON_EXTRACT(target_params,'$.tableName'))='%s'", INVOKE_FILE_EXPORT, tableName) _, err := dborm.XEngDB().Table(s.TableName()). Select("JSON_UNQUOTE(JSON_EXTRACT(target_params, '$.filePath')) as file_path"). Where(where). Get(&querys.Path) if 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 *FileNBI) 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 *FileNBI) GetSingleFileHandler(c *gin.Context) { var querys FileNBIQuery querys.Category = c.Param("category") querys.Type = c.Param("type") querys.DateIndex = c.Param("dateIndex") if err := c.ShouldBindQuery(&querys); err != nil { c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } tableName := "" if querys.Path == "" { ok := false switch querys.Category { case "cdr": tableName, ok = CDRTableMapper[querys.Type] if tableName == "" || !ok { c.JSON(http.StatusOK, services.ErrResp(fmt.Sprintf("invalid CDR file type: %s", querys.Type))) return } case "log": tableName, ok = LogTableMapper[querys.Type] if tableName == "" || !ok { c.JSON(http.StatusOK, services.ErrResp(fmt.Sprintf("invalid log file type: %s", querys.Type))) return } default: c.JSON(http.StatusOK, services.ErrResp(fmt.Sprintf("invalid log file category: %s", querys.Category))) return } s := SysJob{} where := fmt.Sprintf("invoke_target='%s' and status=1 and JSON_UNQUOTE(JSON_EXTRACT(target_params,'$.tableName'))='%s'", INVOKE_FILE_EXPORT, tableName) _, err := dborm.XEngDB().Table(s.TableName()). Select("JSON_UNQUOTE(JSON_EXTRACT(target_params, '$.filePath')) as file_path"). Where(where). Get(&querys.Path) if err != nil { c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } } fileName := tableName + "_export_" + querys.DateIndex + "0000" + ".csv" filePath := filepath.Join(querys.Path, 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 *FileNBI) GetMultiFileHandler(c *gin.Context) { var querys FileNBIQuery querys.Category = c.Param("category") querys.Type = c.Param("type") if err := c.ShouldBindQuery(&querys); err != nil { c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } tableName := "" if querys.Path == "" { ok := false switch querys.Category { case "cdr": tableName, ok = CDRTableMapper[querys.Type] if tableName == "" || !ok { c.JSON(http.StatusOK, services.ErrResp(fmt.Sprintf("invalid CDR file type: %s", querys.Type))) return } case "log": tableName, ok = LogTableMapper[querys.Type] if tableName == "" || !ok { c.JSON(http.StatusOK, services.ErrResp(fmt.Sprintf("invalid log file type: %s", querys.Type))) return } default: c.JSON(http.StatusOK, services.ErrResp(fmt.Sprintf("invalid log file category: %s", querys.Category))) return } s := SysJob{} where := fmt.Sprintf("invoke_target='%s' and status=1 and JSON_UNQUOTE(JSON_EXTRACT(target_params,'$.tableName'))='%s'", INVOKE_FILE_EXPORT, tableName) _, err := dborm.XEngDB().Table(s.TableName()). Select("JSON_UNQUOTE(JSON_EXTRACT(target_params, '$.filePath')) as file_path"). Where(where). Get(&querys.Path) if err != nil { c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } } zipWriter := zip.NewWriter(c.Writer) defer zipWriter.Close() for _, fileName := range querys.FileNames { filePath := filepath.Join(querys.Path, 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 } writer, err := zipWriter.Create(filepath.Base(fileName)) if err != nil { c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } if _, err := io.Copy(writer, file); err != nil { c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } } zipFile := tableName + "_export_" + time.Now().Local().Format(global.DateData) + ".zip" c.Header("Content-Disposition", "attachment; filename="+zipFile) c.Header("Content-Type", "application/zip") //c.File(filePath) }