2021-09-11 14:04:09 +08:00
|
|
|
|
package api
|
2021-05-08 18:00:33 +08:00
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"fmt"
|
2022-08-29 21:43:24 +08:00
|
|
|
|
"io"
|
2021-05-08 18:00:33 +08:00
|
|
|
|
"io/fs"
|
2022-09-09 18:26:08 +08:00
|
|
|
|
"mayfly-go/internal/machine/api/form"
|
|
|
|
|
|
"mayfly-go/internal/machine/api/vo"
|
|
|
|
|
|
"mayfly-go/internal/machine/application"
|
2024-05-09 21:29:34 +08:00
|
|
|
|
"mayfly-go/internal/machine/application/dto"
|
2023-11-12 20:14:44 +08:00
|
|
|
|
"mayfly-go/internal/machine/config"
|
2022-09-09 18:26:08 +08:00
|
|
|
|
"mayfly-go/internal/machine/domain/entity"
|
2024-11-20 22:43:53 +08:00
|
|
|
|
"mayfly-go/internal/machine/imsg"
|
2023-10-30 17:34:56 +08:00
|
|
|
|
"mayfly-go/internal/machine/mcm"
|
2023-07-03 21:42:04 +08:00
|
|
|
|
msgapp "mayfly-go/internal/msg/application"
|
2023-10-10 17:39:46 +08:00
|
|
|
|
msgdto "mayfly-go/internal/msg/application/dto"
|
2022-06-02 17:41:11 +08:00
|
|
|
|
"mayfly-go/pkg/biz"
|
2023-10-26 17:15:49 +08:00
|
|
|
|
"mayfly-go/pkg/errorx"
|
2024-11-20 22:43:53 +08:00
|
|
|
|
"mayfly-go/pkg/i18n"
|
2023-09-08 22:24:45 +08:00
|
|
|
|
"mayfly-go/pkg/logx"
|
2023-01-14 16:29:52 +08:00
|
|
|
|
"mayfly-go/pkg/req"
|
2023-10-20 21:31:46 +08:00
|
|
|
|
"mayfly-go/pkg/utils/anyx"
|
2023-09-08 22:24:45 +08:00
|
|
|
|
"mayfly-go/pkg/utils/collx"
|
2023-09-06 18:06:52 +08:00
|
|
|
|
"mayfly-go/pkg/utils/timex"
|
2023-09-08 22:24:45 +08:00
|
|
|
|
"mime/multipart"
|
2024-04-06 04:03:38 +00:00
|
|
|
|
"os"
|
2023-09-08 22:24:45 +08:00
|
|
|
|
"path/filepath"
|
2022-09-26 18:08:12 +08:00
|
|
|
|
"sort"
|
2021-05-08 18:00:33 +08:00
|
|
|
|
"strings"
|
2023-09-08 22:24:45 +08:00
|
|
|
|
"sync"
|
2024-04-09 12:55:51 +08:00
|
|
|
|
|
|
|
|
|
|
"github.com/may-fly/cast"
|
2024-05-21 12:34:26 +08:00
|
|
|
|
"github.com/pkg/sftp"
|
2021-05-08 18:00:33 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type MachineFile struct {
|
2024-05-21 12:34:26 +08:00
|
|
|
|
MachineApp application.Machine `inject:""`
|
2024-01-21 22:52:20 +08:00
|
|
|
|
MachineFileApp application.MachineFile `inject:""`
|
|
|
|
|
|
MsgApp msgapp.Msg `inject:""`
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
|
file = "-"
|
|
|
|
|
|
dir = "d"
|
|
|
|
|
|
link = "l"
|
2021-06-07 17:22:07 +08:00
|
|
|
|
max_read_size = 1 * 1024 * 1024
|
2021-05-08 18:00:33 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-01-14 16:29:52 +08:00
|
|
|
|
func (m *MachineFile) MachineFiles(rc *req.Ctx) {
|
2024-02-24 16:30:29 +08:00
|
|
|
|
condition := &entity.MachineFile{MachineId: GetMachineId(rc)}
|
2024-02-25 12:46:18 +08:00
|
|
|
|
res, err := m.MachineFileApp.GetPageList(condition, rc.GetPageParam(), new([]vo.MachineFileVO))
|
2023-10-26 17:15:49 +08:00
|
|
|
|
biz.ErrIsNil(err)
|
|
|
|
|
|
rc.ResData = res
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-14 16:29:52 +08:00
|
|
|
|
func (m *MachineFile) SaveMachineFiles(rc *req.Ctx) {
|
2021-05-08 18:00:33 +08:00
|
|
|
|
fileForm := new(form.MachineFileForm)
|
2024-02-24 16:30:29 +08:00
|
|
|
|
entity := req.BindJsonAndCopyTo[*entity.MachineFile](rc, fileForm, new(entity.MachineFile))
|
2021-05-08 18:00:33 +08:00
|
|
|
|
|
2023-07-08 20:05:55 +08:00
|
|
|
|
rc.ReqParam = fileForm
|
2023-11-07 21:05:21 +08:00
|
|
|
|
biz.ErrIsNil(m.MachineFileApp.Save(rc.MetaCtx, entity))
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-14 16:29:52 +08:00
|
|
|
|
func (m *MachineFile) DeleteFile(rc *req.Ctx) {
|
2024-02-24 16:30:29 +08:00
|
|
|
|
biz.ErrIsNil(m.MachineFileApp.DeleteById(rc.MetaCtx, GetMachineFileId(rc)))
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*** sftp相关操作 */
|
|
|
|
|
|
|
2023-01-14 16:29:52 +08:00
|
|
|
|
func (m *MachineFile) CreateFile(rc *req.Ctx) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
opForm := req.BindJsonAndValid(rc, new(form.CreateFileForm))
|
2024-04-06 04:03:38 +00:00
|
|
|
|
path := opForm.Path
|
2022-07-04 20:21:24 +08:00
|
|
|
|
|
2023-10-12 12:14:56 +08:00
|
|
|
|
attrs := collx.Kvs("path", path)
|
2023-10-30 17:34:56 +08:00
|
|
|
|
var mi *mcm.MachineInfo
|
2023-09-11 22:59:13 +08:00
|
|
|
|
var err error
|
2024-04-06 04:03:38 +00:00
|
|
|
|
if opForm.Type == dir {
|
2024-11-20 22:43:53 +08:00
|
|
|
|
attrs["type"] = "Folder"
|
2024-05-09 21:29:34 +08:00
|
|
|
|
mi, err = m.MachineFileApp.MkDir(rc.MetaCtx, opForm.MachineFileOp)
|
2022-07-04 20:21:24 +08:00
|
|
|
|
} else {
|
2024-11-20 22:43:53 +08:00
|
|
|
|
attrs["type"] = "File"
|
2024-05-09 21:29:34 +08:00
|
|
|
|
mi, err = m.MachineFileApp.CreateFile(rc.MetaCtx, opForm.MachineFileOp)
|
2022-07-04 20:21:24 +08:00
|
|
|
|
}
|
2023-09-11 22:59:13 +08:00
|
|
|
|
attrs["machine"] = mi
|
|
|
|
|
|
rc.ReqParam = attrs
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNil(err)
|
2022-07-04 20:21:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-14 16:29:52 +08:00
|
|
|
|
func (m *MachineFile) ReadFileContent(rc *req.Ctx) {
|
2024-05-09 21:29:34 +08:00
|
|
|
|
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
2024-04-06 04:03:38 +00:00
|
|
|
|
readPath := opForm.Path
|
2024-11-20 22:43:53 +08:00
|
|
|
|
ctx := rc.MetaCtx
|
|
|
|
|
|
|
2024-04-06 04:03:38 +00:00
|
|
|
|
// 特殊处理rdp文件
|
|
|
|
|
|
if opForm.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
path := m.MachineFileApp.GetRdpFilePath(rc.GetLoginAccount(), opForm.Path)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
fi, err := os.Stat(path)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNil(err)
|
|
|
|
|
|
biz.IsTrueI(ctx, fi.Size() < max_read_size, imsg.ErrFileTooLargeUseDownload)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
datas, err := os.ReadFile(path)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNil(err)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
rc.ResData = string(datas)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2021-05-08 18:00:33 +08:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
sftpFile, mi, err := m.MachineFileApp.ReadFile(rc.MetaCtx, opForm)
|
2023-10-12 12:14:56 +08:00
|
|
|
|
rc.ReqParam = collx.Kvs("machine", mi, "path", readPath)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNil(err)
|
2022-01-28 11:30:11 +08:00
|
|
|
|
defer sftpFile.Close()
|
|
|
|
|
|
|
|
|
|
|
|
fileInfo, _ := sftpFile.Stat()
|
2023-09-09 23:34:26 +08:00
|
|
|
|
filesize := fileInfo.Size()
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.IsTrueI(ctx, filesize < max_read_size, imsg.ErrFileTooLargeUseDownload)
|
2024-01-12 13:15:30 +08:00
|
|
|
|
|
|
|
|
|
|
datas, err := io.ReadAll(sftpFile)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNil(err)
|
2024-01-12 13:15:30 +08:00
|
|
|
|
|
|
|
|
|
|
rc.ResData = string(datas)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *MachineFile) DownloadFile(rc *req.Ctx) {
|
2024-05-09 21:29:34 +08:00
|
|
|
|
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
2024-04-06 04:03:38 +00:00
|
|
|
|
|
|
|
|
|
|
readPath := opForm.Path
|
|
|
|
|
|
|
|
|
|
|
|
// 截取文件名,如/usr/local/test.java -》 test.java
|
|
|
|
|
|
path := strings.Split(readPath, "/")
|
|
|
|
|
|
fileName := path[len(path)-1]
|
|
|
|
|
|
|
|
|
|
|
|
if opForm.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
path := m.MachineFileApp.GetRdpFilePath(rc.GetLoginAccount(), opForm.Path)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
file, err := os.Open(path)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
rc.Download(file, fileName)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2024-01-12 13:15:30 +08:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
sftpFile, mi, err := m.MachineFileApp.ReadFile(rc.MetaCtx, opForm)
|
2024-01-12 13:15:30 +08:00
|
|
|
|
rc.ReqParam = collx.Kvs("machine", mi, "path", readPath)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "open file error: %s")
|
2024-01-12 13:15:30 +08:00
|
|
|
|
defer sftpFile.Close()
|
|
|
|
|
|
|
2024-04-06 04:03:38 +00:00
|
|
|
|
rc.Download(sftpFile, fileName)
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-14 16:29:52 +08:00
|
|
|
|
func (m *MachineFile) GetDirEntry(rc *req.Ctx) {
|
2024-05-09 21:29:34 +08:00
|
|
|
|
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
2024-04-06 04:03:38 +00:00
|
|
|
|
readPath := opForm.Path
|
2023-08-04 12:22:21 +08:00
|
|
|
|
rc.ReqParam = fmt.Sprintf("path: %s", readPath)
|
2021-05-08 18:00:33 +08:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
fis, err := m.MachineFileApp.ReadDir(rc.MetaCtx, opForm)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "read dir error: %s")
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2021-05-08 18:00:33 +08:00
|
|
|
|
fisVO := make([]vo.MachineFileInfo, 0)
|
|
|
|
|
|
for _, fi := range fis {
|
2024-04-06 04:03:38 +00:00
|
|
|
|
name := fi.Name()
|
|
|
|
|
|
if !strings.HasPrefix(name, "/") {
|
|
|
|
|
|
name = "/" + name
|
|
|
|
|
|
}
|
|
|
|
|
|
path := name
|
|
|
|
|
|
if readPath != "/" && readPath != "" {
|
|
|
|
|
|
path = readPath + name
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-21 12:34:26 +08:00
|
|
|
|
mfi := vo.MachineFileInfo{
|
2023-09-06 18:06:52 +08:00
|
|
|
|
Name: fi.Name(),
|
|
|
|
|
|
Size: fi.Size(),
|
2024-04-06 04:03:38 +00:00
|
|
|
|
Path: path,
|
2023-09-06 18:06:52 +08:00
|
|
|
|
Type: getFileType(fi.Mode()),
|
|
|
|
|
|
Mode: fi.Mode().String(),
|
|
|
|
|
|
ModTime: timex.DefaultFormat(fi.ModTime()),
|
2024-05-21 12:34:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if sftpFs, ok := fi.Sys().(*sftp.FileStat); ok {
|
|
|
|
|
|
mfi.UID = sftpFs.UID
|
|
|
|
|
|
mfi.GID = sftpFs.GID
|
|
|
|
|
|
}
|
2023-09-06 18:06:52 +08:00
|
|
|
|
|
2024-05-21 12:34:26 +08:00
|
|
|
|
fisVO = append(fisVO, mfi)
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
2022-09-26 18:08:12 +08:00
|
|
|
|
sort.Sort(vo.MachineFileInfos(fisVO))
|
2021-05-08 18:00:33 +08:00
|
|
|
|
rc.ResData = fisVO
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-05 00:26:00 +08:00
|
|
|
|
func (m *MachineFile) GetDirSize(rc *req.Ctx) {
|
2024-05-09 21:29:34 +08:00
|
|
|
|
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
2023-07-05 00:26:00 +08:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
size, err := m.MachineFileApp.GetDirSize(rc.MetaCtx, opForm)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
biz.ErrIsNil(err)
|
|
|
|
|
|
rc.ResData = size
|
2023-07-05 00:26:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *MachineFile) GetFileStat(rc *req.Ctx) {
|
2024-05-09 21:29:34 +08:00
|
|
|
|
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
2024-04-19 11:27:29 +00:00
|
|
|
|
res, err := m.MachineFileApp.FileStat(rc.MetaCtx, opForm)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
biz.ErrIsNil(err, res)
|
|
|
|
|
|
rc.ResData = res
|
2023-07-05 00:26:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-14 16:29:52 +08:00
|
|
|
|
func (m *MachineFile) WriteFileContent(rc *req.Ctx) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
opForm := req.BindJsonAndValid(rc, new(form.WriteFileContentForm))
|
2024-04-06 04:03:38 +00:00
|
|
|
|
path := opForm.Path
|
2021-05-08 18:00:33 +08:00
|
|
|
|
|
2024-05-09 21:29:34 +08:00
|
|
|
|
mi, err := m.MachineFileApp.WriteFileContent(rc.MetaCtx, opForm.MachineFileOp, []byte(opForm.Content))
|
2023-10-12 12:14:56 +08:00
|
|
|
|
rc.ReqParam = collx.Kvs("machine", mi, "path", path)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "open file error: %s")
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-14 16:29:52 +08:00
|
|
|
|
func (m *MachineFile) UploadFile(rc *req.Ctx) {
|
2024-02-25 12:46:18 +08:00
|
|
|
|
path := rc.PostForm("path")
|
2024-04-09 12:55:51 +08:00
|
|
|
|
protocol := cast.ToInt(rc.PostForm("protocol"))
|
|
|
|
|
|
machineId := cast.ToUint64(rc.PostForm("machineId"))
|
|
|
|
|
|
authCertName := rc.PostForm("authCertName")
|
2021-11-12 14:35:34 +08:00
|
|
|
|
|
2024-02-25 12:46:18 +08:00
|
|
|
|
fileheader, err := rc.FormFile("file")
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "read form file error: %s")
|
|
|
|
|
|
|
|
|
|
|
|
ctx := rc.MetaCtx
|
2023-11-12 20:14:44 +08:00
|
|
|
|
|
|
|
|
|
|
maxUploadFileSize := config.GetMachine().UploadMaxFileSize
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.IsTrueI(ctx, fileheader.Size <= maxUploadFileSize, imsg.ErrUploadFileOutOfLimit, "size", maxUploadFileSize)
|
2021-05-08 18:00:33 +08:00
|
|
|
|
|
|
|
|
|
|
file, _ := fileheader.Open()
|
2023-09-09 23:34:26 +08:00
|
|
|
|
defer file.Close()
|
2021-12-02 10:35:48 +08:00
|
|
|
|
|
2023-11-07 21:05:21 +08:00
|
|
|
|
la := rc.GetLoginAccount()
|
2023-09-08 22:24:45 +08:00
|
|
|
|
defer func() {
|
2023-10-20 21:31:46 +08:00
|
|
|
|
if anyx.ToString(recover()) != "" {
|
2024-11-20 22:43:53 +08:00
|
|
|
|
logx.Errorf("upload file error: %s", err)
|
|
|
|
|
|
m.MsgApp.CreateAndSend(la, msgdto.ErrSysMsg(i18n.TC(ctx, imsg.ErrFileUploadFail), fmt.Sprintf("%s: \n<-e : %s", i18n.TC(ctx, imsg.ErrFileUploadFail), err)))
|
2023-09-08 22:24:45 +08:00
|
|
|
|
}
|
2021-12-02 10:35:48 +08:00
|
|
|
|
}()
|
2023-09-08 22:24:45 +08:00
|
|
|
|
|
2024-05-09 21:29:34 +08:00
|
|
|
|
opForm := &dto.MachineFileOp{
|
2024-04-09 12:55:51 +08:00
|
|
|
|
MachineId: machineId,
|
|
|
|
|
|
AuthCertName: authCertName,
|
|
|
|
|
|
Protocol: protocol,
|
|
|
|
|
|
Path: path,
|
2024-04-06 04:03:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-20 22:43:53 +08:00
|
|
|
|
mi, err := m.MachineFileApp.UploadFile(ctx, opForm, fileheader.Filename, file)
|
2023-10-12 12:14:56 +08:00
|
|
|
|
rc.ReqParam = collx.Kvs("machine", mi, "path", fmt.Sprintf("%s/%s", path, fileheader.Filename))
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "upload file error: %s")
|
2023-09-08 22:24:45 +08:00
|
|
|
|
// 保存消息并发送文件上传成功通知
|
2024-11-20 22:43:53 +08:00
|
|
|
|
m.MsgApp.CreateAndSend(la, msgdto.SuccessSysMsg(i18n.TC(ctx, imsg.MsgUploadFileSuccess), fmt.Sprintf("[%s] -> %s[%s:%s]", fileheader.Filename, mi.Name, mi.Ip, path)))
|
2023-09-08 22:24:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type FolderFile struct {
|
|
|
|
|
|
Dir string
|
|
|
|
|
|
Fileheader *multipart.FileHeader
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
2024-02-25 12:46:18 +08:00
|
|
|
|
mf, err := rc.MultipartForm()
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "get multipart form error: %s")
|
2023-09-08 22:24:45 +08:00
|
|
|
|
basePath := mf.Value["basePath"][0]
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.NotEmpty(basePath, "basePath cannot be empty")
|
2023-09-08 22:24:45 +08:00
|
|
|
|
|
|
|
|
|
|
fileheaders := mf.File["files"]
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.IsTrue(len(fileheaders) > 0, "files cannot be empty")
|
2023-09-08 22:24:45 +08:00
|
|
|
|
allFileSize := collx.ArrayReduce(fileheaders, 0, func(i int64, fh *multipart.FileHeader) int64 {
|
|
|
|
|
|
return i + fh.Size
|
|
|
|
|
|
})
|
2023-11-12 20:14:44 +08:00
|
|
|
|
|
2024-11-20 22:43:53 +08:00
|
|
|
|
ctx := rc.MetaCtx
|
2023-11-12 20:14:44 +08:00
|
|
|
|
maxUploadFileSize := config.GetMachine().UploadMaxFileSize
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.IsTrueI(ctx, allFileSize <= maxUploadFileSize, imsg.ErrUploadFileOutOfLimit, "size", maxUploadFileSize)
|
2023-09-08 22:24:45 +08:00
|
|
|
|
|
|
|
|
|
|
paths := mf.Value["paths"]
|
2024-04-09 12:55:51 +08:00
|
|
|
|
authCertName := mf.Value["authCertName"][0]
|
|
|
|
|
|
machineId := cast.ToUint64(mf.Value["machineId"][0])
|
2024-04-06 04:03:38 +00:00
|
|
|
|
// protocol
|
2024-04-09 12:55:51 +08:00
|
|
|
|
protocol := cast.ToInt(mf.Value["protocol"][0])
|
|
|
|
|
|
|
2024-05-09 21:29:34 +08:00
|
|
|
|
opForm := &dto.MachineFileOp{
|
2024-04-09 12:55:51 +08:00
|
|
|
|
MachineId: machineId,
|
|
|
|
|
|
Protocol: protocol,
|
|
|
|
|
|
AuthCertName: authCertName,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-06 04:03:38 +00:00
|
|
|
|
if protocol == entity.MachineProtocolRdp {
|
2024-11-20 22:43:53 +08:00
|
|
|
|
m.MachineFileApp.UploadFiles(ctx, opForm, basePath, fileheaders, paths)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-09-08 22:24:45 +08:00
|
|
|
|
folderName := filepath.Dir(paths[0])
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mcli, err := m.MachineFileApp.GetMachineCli(authCertName)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
biz.ErrIsNil(err)
|
2023-10-30 17:34:56 +08:00
|
|
|
|
mi := mcli.Info
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
sftpCli, err := mcli.GetSftpCli()
|
|
|
|
|
|
biz.ErrIsNil(err)
|
2023-10-12 12:14:56 +08:00
|
|
|
|
rc.ReqParam = collx.Kvs("machine", mi, "path", fmt.Sprintf("%s/%s", basePath, folderName))
|
2023-09-08 22:24:45 +08:00
|
|
|
|
|
|
|
|
|
|
folderFiles := make([]FolderFile, len(paths))
|
|
|
|
|
|
// 先创建目录,并将其包装为folderFile结构
|
|
|
|
|
|
mkdirs := make(map[string]bool, 0)
|
|
|
|
|
|
for i, path := range paths {
|
|
|
|
|
|
dir := filepath.Dir(path)
|
|
|
|
|
|
// 目录已建,则无需重复建
|
|
|
|
|
|
if !mkdirs[dir] {
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(sftpCli.MkdirAll(basePath+"/"+dir), "create dir error: %s")
|
2023-09-08 22:24:45 +08:00
|
|
|
|
mkdirs[dir] = true
|
|
|
|
|
|
}
|
|
|
|
|
|
folderFiles[i] = FolderFile{
|
|
|
|
|
|
Dir: dir,
|
|
|
|
|
|
Fileheader: fileheaders[i],
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 分组处理
|
2023-09-11 22:59:13 +08:00
|
|
|
|
groupNum := 30
|
2023-09-08 22:24:45 +08:00
|
|
|
|
chunks := collx.ArraySplit(folderFiles, groupNum)
|
|
|
|
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
|
// 设置要等待的协程数量
|
|
|
|
|
|
wg.Add(len(chunks))
|
|
|
|
|
|
|
2023-10-30 17:34:56 +08:00
|
|
|
|
isSuccess := true
|
2023-11-07 21:05:21 +08:00
|
|
|
|
la := rc.GetLoginAccount()
|
2023-09-08 22:24:45 +08:00
|
|
|
|
for _, chunk := range chunks {
|
|
|
|
|
|
go func(files []FolderFile, wg *sync.WaitGroup) {
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
// 协程执行完成后调用Done方法
|
|
|
|
|
|
wg.Done()
|
|
|
|
|
|
if err := recover(); err != nil {
|
2023-10-30 17:34:56 +08:00
|
|
|
|
isSuccess = false
|
2024-11-20 22:43:53 +08:00
|
|
|
|
logx.Errorf("upload file error: %s", err)
|
2023-09-08 22:24:45 +08:00
|
|
|
|
switch t := err.(type) {
|
2024-10-23 17:30:05 +08:00
|
|
|
|
case *errorx.BizError:
|
2024-11-20 22:43:53 +08:00
|
|
|
|
m.MsgApp.CreateAndSend(la, msgdto.ErrSysMsg(i18n.TC(ctx, imsg.ErrFileUploadFail), fmt.Sprintf("%s: \n<-e errCode: %d, errMsg: %s", i18n.TC(ctx, imsg.ErrFileUploadFail), t.Code(), t.Error())))
|
2023-09-08 22:24:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
for _, file := range files {
|
|
|
|
|
|
fileHeader := file.Fileheader
|
|
|
|
|
|
dir := file.Dir
|
|
|
|
|
|
file, _ := fileHeader.Open()
|
|
|
|
|
|
defer file.Close()
|
2023-09-11 22:59:13 +08:00
|
|
|
|
|
2024-11-20 22:43:53 +08:00
|
|
|
|
logx.Debugf("upload folder: dir=%s -> filename=%s", dir, fileHeader.Filename)
|
2023-09-11 22:59:13 +08:00
|
|
|
|
|
|
|
|
|
|
createfile, err := sftpCli.Create(fmt.Sprintf("%s/%s/%s", basePath, dir, fileHeader.Filename))
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "create file error: %s")
|
2023-09-11 22:59:13 +08:00
|
|
|
|
defer createfile.Close()
|
|
|
|
|
|
io.Copy(createfile, file)
|
2023-09-08 22:24:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
}(chunk, &wg)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 等待所有协程执行完成
|
|
|
|
|
|
wg.Wait()
|
2023-10-30 17:34:56 +08:00
|
|
|
|
if isSuccess {
|
|
|
|
|
|
// 保存消息并发送文件上传成功通知
|
2024-11-20 22:43:53 +08:00
|
|
|
|
m.MsgApp.CreateAndSend(la, msgdto.SuccessSysMsg(i18n.TC(ctx, imsg.MsgUploadFileSuccess), fmt.Sprintf("[%s] -> %s[%s:%s]", folderName, mi.Name, mi.Ip, basePath)))
|
2023-10-30 17:34:56 +08:00
|
|
|
|
}
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-14 16:29:52 +08:00
|
|
|
|
func (m *MachineFile) RemoveFile(rc *req.Ctx) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
opForm := req.BindJsonAndValid(rc, new(form.RemoveFileForm))
|
2023-09-07 16:33:53 +08:00
|
|
|
|
|
2024-05-09 21:29:34 +08:00
|
|
|
|
mi, err := m.MachineFileApp.RemoveFile(rc.MetaCtx, opForm.MachineFileOp, opForm.Paths...)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
rc.ReqParam = collx.Kvs("machine", mi, "path", opForm)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "remove file error: %s")
|
2023-09-07 16:33:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *MachineFile) CopyFile(rc *req.Ctx) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
opForm := req.BindJsonAndValid(rc, new(form.CopyFileForm))
|
2024-05-09 21:29:34 +08:00
|
|
|
|
mi, err := m.MachineFileApp.Copy(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "file copy error: %s")
|
2024-04-06 04:03:38 +00:00
|
|
|
|
rc.ReqParam = collx.Kvs("machine", mi, "cp", opForm)
|
2023-09-07 16:33:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *MachineFile) MvFile(rc *req.Ctx) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
opForm := req.BindJsonAndValid(rc, new(form.CopyFileForm))
|
2024-05-09 21:29:34 +08:00
|
|
|
|
mi, err := m.MachineFileApp.Mv(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
rc.ReqParam = collx.Kvs("machine", mi, "mv", opForm)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "file move error: %s")
|
2023-09-07 16:33:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *MachineFile) Rename(rc *req.Ctx) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
renameForm := req.BindJsonAndValid(rc, new(form.RenameForm))
|
2024-05-09 21:29:34 +08:00
|
|
|
|
mi, err := m.MachineFileApp.Rename(rc.MetaCtx, renameForm.MachineFileOp, renameForm.Newname)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
rc.ReqParam = collx.Kvs("machine", mi, "rename", renameForm)
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.ErrIsNilAppendErr(err, "file rename error: %s")
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func getFileType(fm fs.FileMode) string {
|
|
|
|
|
|
if fm.IsDir() {
|
|
|
|
|
|
return dir
|
|
|
|
|
|
}
|
2022-07-04 20:21:24 +08:00
|
|
|
|
if fm.IsRegular() {
|
|
|
|
|
|
return file
|
|
|
|
|
|
}
|
|
|
|
|
|
return dir
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-24 16:30:29 +08:00
|
|
|
|
func GetMachineFileId(rc *req.Ctx) uint64 {
|
2024-02-25 12:46:18 +08:00
|
|
|
|
fileId := rc.PathParamInt("fileId")
|
2024-11-20 22:43:53 +08:00
|
|
|
|
biz.IsTrue(fileId != 0, "fileId error")
|
2021-05-08 18:00:33 +08:00
|
|
|
|
return uint64(fileId)
|
|
|
|
|
|
}
|