302 lines
8.1 KiB
Go
302 lines
8.1 KiB
Go
package file_export
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
|
|
"be.ems/lib/file"
|
|
"be.ems/lib/log"
|
|
"be.ems/lib/services"
|
|
"be.ems/src/framework/config"
|
|
"be.ems/src/framework/datasource"
|
|
"be.ems/src/framework/i18n"
|
|
"be.ems/src/framework/utils/crypto"
|
|
"be.ems/src/framework/utils/ctx"
|
|
"be.ems/src/framework/utils/ssh"
|
|
"be.ems/src/framework/vo/result"
|
|
systemService "be.ems/src/modules/system/service"
|
|
"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 *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 {
|
|
var params TargetParams
|
|
if err := json.Unmarshal([]byte(job.TargetParams), ¶ms); err != nil {
|
|
c.JSON(http.StatusOK, services.ErrResp(err.Error()))
|
|
return
|
|
}
|
|
TableDisplay := i18n.TKey(language, "table."+params.TableName)
|
|
if TableDisplay == "" {
|
|
TableDisplay = params.TableName
|
|
}
|
|
response = append(response, SysJobResponse{
|
|
SysJob: job,
|
|
TableName: params.TableName,
|
|
TableDisplay: TableDisplay,
|
|
FilePath: params.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
|
|
}
|
|
|
|
// 设置FTP配置
|
|
// POST /table/ftp
|
|
func (m *SysJob) SetFTPConfig(c *gin.Context) {
|
|
language := ctx.AcceptLanguage(c)
|
|
var body struct {
|
|
Password string `json:"password" `
|
|
Username string `json:"username" binding:"required"`
|
|
ToIp string `json:"toIp" binding:"required"`
|
|
ToPort int64 `json:"toPort" binding:"required"`
|
|
Enable bool `json:"enable"`
|
|
Dir string `json:"dir" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
|
return
|
|
}
|
|
|
|
// 获取配置
|
|
cfg := systemService.NewSysConfigImpl.SelectConfigByKey("sys.exportTable")
|
|
if cfg.ConfigID != "" {
|
|
// 加密body
|
|
appKey := config.Get("aes.appKey").(string)
|
|
byteData, err := json.Marshal(body)
|
|
if err != nil {
|
|
c.JSON(200, result.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
bodyEn, err := crypto.AESEncryptBase64(string(byteData), appKey)
|
|
if err != nil {
|
|
c.JSON(200, result.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
// 更新
|
|
cfg.ConfigValue = bodyEn
|
|
systemService.NewSysConfigImpl.UpdateConfig(cfg)
|
|
}
|
|
|
|
c.JSON(200, result.Ok(nil))
|
|
}
|
|
|
|
// 获取FTP配置
|
|
// GET /table/ftp
|
|
func (m *SysJob) GetFTPConfig(c *gin.Context) {
|
|
// 获取配置
|
|
cfg := systemService.NewSysConfigImpl.SelectConfigByKey("sys.exportTable")
|
|
if cfg.ConfigID != "" {
|
|
// 解密body
|
|
appKey := config.Get("aes.appKey").(string)
|
|
bodyDe, err := crypto.AESDecryptBase64(cfg.ConfigValue, appKey)
|
|
if err != nil {
|
|
c.JSON(200, result.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
var body struct {
|
|
Password string `json:"password" `
|
|
Username string `json:"username" binding:"required"`
|
|
ToIp string `json:"toIp" binding:"required"`
|
|
ToPort int64 `json:"toPort" binding:"required"`
|
|
Enable bool `json:"enable"`
|
|
Dir string `json:"dir" binding:"required"`
|
|
}
|
|
err = json.Unmarshal([]byte(bodyDe), &body)
|
|
if err != nil {
|
|
c.JSON(200, result.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
c.JSON(200, result.OkData(body))
|
|
return
|
|
}
|
|
|
|
c.JSON(200, result.Ok(nil))
|
|
}
|
|
|
|
// FTP发送
|
|
// PUT /table/ftp
|
|
func (m *SysJob) PutFTP(c *gin.Context) {
|
|
language := ctx.AcceptLanguage(c)
|
|
var body struct {
|
|
FilePath string `json:"filePath" binding:"required"`
|
|
FileName string `json:"fileName" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
|
return
|
|
}
|
|
|
|
localFilePath := filepath.Join(body.FilePath, body.FileName)
|
|
|
|
// 判断文件是否存在
|
|
if _, err := os.Stat(localFilePath); os.IsNotExist(err) {
|
|
c.JSON(200, result.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
|
|
// 获取配置
|
|
var cfgData struct {
|
|
Password string `json:"password" `
|
|
Username string `json:"username" binding:"required"`
|
|
ToIp string `json:"toIp" binding:"required"`
|
|
ToPort int64 `json:"toPort" binding:"required"`
|
|
Enable bool `json:"enable"`
|
|
Dir string `json:"dir" binding:"required"`
|
|
}
|
|
cfg := systemService.NewSysConfigImpl.SelectConfigByKey("sys.exportTable")
|
|
if cfg.ConfigID != "" {
|
|
// 解密body
|
|
appKey := config.Get("aes.appKey").(string)
|
|
bodyDe, err := crypto.AESDecryptBase64(cfg.ConfigValue, appKey)
|
|
if err != nil {
|
|
c.JSON(200, result.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
err = json.Unmarshal([]byte(bodyDe), &cfgData)
|
|
if err != nil {
|
|
c.JSON(200, result.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
}
|
|
if !cfgData.Enable {
|
|
c.JSON(200, result.ErrMsg("Setting Remote Backup is disabled"))
|
|
return
|
|
}
|
|
|
|
connSSH := ssh.ConnSSH{
|
|
User: cfgData.Username,
|
|
Password: cfgData.Password,
|
|
Addr: cfgData.ToIp,
|
|
Port: cfgData.ToPort,
|
|
AuthMode: "0",
|
|
}
|
|
sshClient, err := connSSH.NewClient()
|
|
if err != nil {
|
|
c.JSON(200, result.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sshClient.Close()
|
|
// 网元主机的SSH客户端进行文件传输
|
|
sftpClient, err := sshClient.NewClientSFTP()
|
|
if err != nil {
|
|
c.JSON(200, result.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sftpClient.Close()
|
|
// 远程文件
|
|
remotePath := filepath.Join(cfgData.Dir, path.Base(body.FilePath), body.FileName)
|
|
// 复制到远程
|
|
if err = sftpClient.CopyFileLocalToRemote(localFilePath, remotePath); err != nil {
|
|
c.JSON(200, result.ErrMsg("error uploading file"))
|
|
return
|
|
}
|
|
c.JSON(200, result.Ok(nil))
|
|
}
|