add: send files
This commit is contained in:
@@ -19,6 +19,12 @@ import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (s *Service) SendFiles(target *discovery.Peer, targetIP string, filePaths []string) {
|
||||
for _, filePath := range filePaths {
|
||||
go s.SendFile(target, targetIP, filePath)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) SendFile(target *discovery.Peer, targetIP string, filePath string) {
|
||||
taskID := uuid.New().String()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@@ -28,6 +34,7 @@ func (s *Service) SendFile(target *discovery.Peer, targetIP string, filePath str
|
||||
defer func() {
|
||||
s.cancelMap.Delete(taskID)
|
||||
cancel()
|
||||
s.NotifyTransferListUpdate()
|
||||
}()
|
||||
|
||||
file, err := os.Open(filePath)
|
||||
@@ -42,21 +49,19 @@ func (s *Service) SendFile(target *discovery.Peer, targetIP string, filePath str
|
||||
return
|
||||
}
|
||||
|
||||
task := Transfer{
|
||||
ID: taskID,
|
||||
FileName: filepath.Base(filePath),
|
||||
FileSize: stat.Size(),
|
||||
Sender: Sender{
|
||||
task := NewTransfer(
|
||||
taskID,
|
||||
Sender{
|
||||
ID: s.discoveryService.GetID(),
|
||||
Name: s.discoveryService.GetName(),
|
||||
},
|
||||
Type: TransferTypeSend,
|
||||
Status: TransferStatusPending,
|
||||
ContentType: ContentTypeFile,
|
||||
}
|
||||
WithFileName(filepath.Base(filePath)),
|
||||
WithFileSize(stat.Size()),
|
||||
WithType(TransferTypeSend),
|
||||
WithContentType(ContentTypeFile),
|
||||
)
|
||||
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
s.StoreTransferToList(task)
|
||||
|
||||
askResp, err := s.ask(ctx, target, targetIP, task)
|
||||
if err != nil {
|
||||
@@ -67,8 +72,6 @@ func (s *Service) SendFile(target *discovery.Peer, targetIP string, filePath str
|
||||
task.Status = TransferStatusError
|
||||
task.ErrorMsg = fmt.Sprintf("Failed to connect to receiver: %v", err)
|
||||
}
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
if askResp.Accepted {
|
||||
@@ -76,8 +79,6 @@ func (s *Service) SendFile(target *discovery.Peer, targetIP string, filePath str
|
||||
} else {
|
||||
// 接收方拒绝
|
||||
task.Status = TransferStatusRejected
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -91,6 +92,7 @@ func (s *Service) SendFolder(target *discovery.Peer, targetIP string, folderPath
|
||||
defer func() {
|
||||
s.cancelMap.Delete(taskID)
|
||||
cancel()
|
||||
s.NotifyTransferListUpdate()
|
||||
}()
|
||||
|
||||
size, err := calculateTarSize(ctx, folderPath)
|
||||
@@ -99,29 +101,29 @@ func (s *Service) SendFolder(target *discovery.Peer, targetIP string, folderPath
|
||||
return
|
||||
}
|
||||
|
||||
task := Transfer{
|
||||
ID: taskID,
|
||||
FileName: filepath.Base(folderPath),
|
||||
FileSize: size,
|
||||
Sender: Sender{
|
||||
task := NewTransfer(
|
||||
taskID,
|
||||
Sender{
|
||||
ID: s.discoveryService.GetID(),
|
||||
Name: s.discoveryService.GetName(),
|
||||
},
|
||||
Type: TransferTypeSend,
|
||||
Status: TransferStatusPending,
|
||||
ContentType: ContentTypeFolder,
|
||||
}
|
||||
WithFileName(filepath.Base(folderPath)),
|
||||
WithFileSize(size),
|
||||
WithType(TransferTypeSend),
|
||||
WithContentType(ContentTypeFolder),
|
||||
)
|
||||
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
s.StoreTransferToList(task)
|
||||
|
||||
askResp, err := s.ask(ctx, target, targetIP, task)
|
||||
if err != nil {
|
||||
// 如果请求发送失败,更新状态为 Error
|
||||
task.Status = TransferStatusError
|
||||
task.ErrorMsg = fmt.Sprintf("Failed to connect to receiver: %v", err)
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
if errors.Is(err, context.Canceled) {
|
||||
task.Status = TransferStatusCanceled
|
||||
} else {
|
||||
// 如果请求发送失败,更新状态为 Error
|
||||
task.Status = TransferStatusError
|
||||
task.ErrorMsg = fmt.Sprintf("Failed to connect to receiver: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if askResp.Accepted {
|
||||
@@ -137,9 +139,6 @@ func (s *Service) SendFolder(target *discovery.Peer, targetIP string, folderPath
|
||||
} else {
|
||||
// 接收方拒绝
|
||||
task.Status = TransferStatusRejected
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,32 +151,32 @@ func (s *Service) SendText(target *discovery.Peer, targetIP string, text string)
|
||||
defer func() {
|
||||
s.cancelMap.Delete(taskID)
|
||||
cancel()
|
||||
s.NotifyTransferListUpdate()
|
||||
}()
|
||||
|
||||
r := bytes.NewReader([]byte(text))
|
||||
task := Transfer{
|
||||
ID: taskID,
|
||||
FileName: "",
|
||||
FileSize: int64(len(text)),
|
||||
Sender: Sender{
|
||||
task := NewTransfer(
|
||||
taskID,
|
||||
Sender{
|
||||
ID: s.discoveryService.GetID(),
|
||||
Name: s.discoveryService.GetName(),
|
||||
},
|
||||
Type: TransferTypeSend,
|
||||
Status: TransferStatusPending,
|
||||
ContentType: ContentTypeText,
|
||||
}
|
||||
WithFileSize(int64(len(text))),
|
||||
WithType(TransferTypeSend),
|
||||
WithContentType(ContentTypeText),
|
||||
)
|
||||
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
s.StoreTransferToList(task)
|
||||
|
||||
askResp, err := s.ask(ctx, target, targetIP, task)
|
||||
if err != nil {
|
||||
// 如果请求发送失败,更新状态为 Error
|
||||
task.Status = TransferStatusError
|
||||
task.ErrorMsg = fmt.Sprintf("Failed to connect to receiver: %v", err)
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
if errors.Is(err, context.Canceled) {
|
||||
task.Status = TransferStatusCanceled
|
||||
} else {
|
||||
// 如果请求发送失败,更新状态为 Error
|
||||
task.Status = TransferStatusError
|
||||
task.ErrorMsg = fmt.Sprintf("Failed to connect to receiver: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if askResp.Accepted {
|
||||
@@ -185,14 +184,12 @@ func (s *Service) SendText(target *discovery.Peer, targetIP string, text string)
|
||||
} else {
|
||||
// 接收方拒绝
|
||||
task.Status = TransferStatusRejected
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ask 向接收端发送传输请求
|
||||
func (s *Service) ask(ctx context.Context, target *discovery.Peer, targetIP string, task Transfer) (TransferAskResponse, error) {
|
||||
func (s *Service) ask(ctx context.Context, target *discovery.Peer, targetIP string, task *Transfer) (TransferAskResponse, error) {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return TransferAskResponse{}, err
|
||||
}
|
||||
@@ -225,7 +222,11 @@ func (s *Service) ask(ctx context.Context, target *discovery.Peer, targetIP stri
|
||||
}
|
||||
|
||||
// processTransfer 传输数据
|
||||
func (s *Service) processTransfer(ctx context.Context, askResp TransferAskResponse, target *discovery.Peer, targetIP string, task Transfer, payload io.Reader) {
|
||||
func (s *Service) processTransfer(ctx context.Context, askResp TransferAskResponse, target *discovery.Peer, targetIP string, task *Transfer, payload io.Reader) {
|
||||
defer func() {
|
||||
s.NotifyTransferListUpdate()
|
||||
}()
|
||||
|
||||
if err := ctx.Err(); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -244,8 +245,7 @@ func (s *Service) processTransfer(ctx context.Context, askResp TransferAskRespon
|
||||
Speed: speed,
|
||||
}
|
||||
task.Status = TransferStatusActive
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
s.NotifyTransferListUpdate()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -265,8 +265,6 @@ func (s *Service) processTransfer(ctx context.Context, askResp TransferAskRespon
|
||||
task.ErrorMsg = fmt.Sprintf("Failed to upload file: %v", err)
|
||||
slog.Error("Failed to upload file", "url", uploadUrl.String(), "error", err, "component", "transfer-client")
|
||||
}
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
@@ -279,8 +277,6 @@ func (s *Service) processTransfer(ctx context.Context, askResp TransferAskRespon
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
task.Status = TransferStatusError
|
||||
task.ErrorMsg = uploadResp.Message
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -288,15 +284,11 @@ func (s *Service) processTransfer(ctx context.Context, askResp TransferAskRespon
|
||||
if uploadResp.Status == TransferStatusCanceled {
|
||||
task.Status = TransferStatusCanceled
|
||||
task.ErrorMsg = uploadResp.Message
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
|
||||
// 传输成功,任务结束
|
||||
task.Status = TransferStatusCompleted
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
}
|
||||
|
||||
type countWriter struct {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package transfer
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type TransferStatus string
|
||||
|
||||
const (
|
||||
@@ -30,6 +34,7 @@ const (
|
||||
// Transfer
|
||||
type Transfer struct {
|
||||
ID string `json:"id" binding:"required"` // 传输会话 ID
|
||||
CreateTime int64 `json:"create_time"` // 创建时间
|
||||
Sender Sender `json:"sender" binding:"required"` // 发送者
|
||||
FileName string `json:"file_name"` // 文件名
|
||||
FileSize int64 `json:"file_size"` // 文件大小 (字节)
|
||||
@@ -44,6 +49,77 @@ type Transfer struct {
|
||||
DecisionChan chan Decision `json:"-"` // 用户决策通道
|
||||
}
|
||||
|
||||
type TransferOption func(*Transfer)
|
||||
|
||||
func NewTransfer(id string, sender Sender, opts ...TransferOption) *Transfer {
|
||||
t := &Transfer{
|
||||
ID: id,
|
||||
CreateTime: time.Now().UnixMilli(),
|
||||
Sender: sender,
|
||||
Status: TransferStatusPending, // Default status
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(t)
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func WithFileName(name string) TransferOption {
|
||||
return func(t *Transfer) {
|
||||
t.FileName = name
|
||||
}
|
||||
}
|
||||
|
||||
func WithFileSize(size int64) TransferOption {
|
||||
return func(t *Transfer) {
|
||||
t.FileSize = size
|
||||
}
|
||||
}
|
||||
|
||||
func WithSavePath(path string) TransferOption {
|
||||
return func(t *Transfer) {
|
||||
t.SavePath = path
|
||||
}
|
||||
}
|
||||
|
||||
func WithStatus(status TransferStatus) TransferOption {
|
||||
return func(t *Transfer) {
|
||||
t.Status = status
|
||||
}
|
||||
}
|
||||
|
||||
func WithType(transType TransferType) TransferOption {
|
||||
return func(t *Transfer) {
|
||||
t.Type = transType
|
||||
}
|
||||
}
|
||||
|
||||
func WithContentType(contentType ContentType) TransferOption {
|
||||
return func(t *Transfer) {
|
||||
t.ContentType = contentType
|
||||
}
|
||||
}
|
||||
|
||||
func WithText(text string) TransferOption {
|
||||
return func(t *Transfer) {
|
||||
t.Text = text
|
||||
}
|
||||
}
|
||||
|
||||
func WithErrorMsg(msg string) TransferOption {
|
||||
return func(t *Transfer) {
|
||||
t.ErrorMsg = msg
|
||||
}
|
||||
}
|
||||
|
||||
func WithToken(token string) TransferOption {
|
||||
return func(t *Transfer) {
|
||||
t.Token = token
|
||||
}
|
||||
}
|
||||
|
||||
type Sender struct {
|
||||
ID string `json:"id" binding:"required"` // 发送者 ID
|
||||
Name string `json:"name" binding:"required"` // 发送者名称
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
// handleAsk 处理接收文件请求
|
||||
func (s *Service) handleAsk(c *gin.Context) {
|
||||
defer s.NotifyTransferListUpdate()
|
||||
var task Transfer
|
||||
|
||||
if err := c.ShouldBindJSON(&task); err != nil {
|
||||
@@ -39,10 +40,9 @@ func (s *Service) handleAsk(c *gin.Context) {
|
||||
task.Type = TransferTypeReceive
|
||||
task.Status = TransferStatusPending
|
||||
task.DecisionChan = make(chan Decision)
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.StoreTransferToList(&task)
|
||||
|
||||
// 通知 Wails 前端
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
|
||||
// 等待用户决策或发送端放弃
|
||||
select {
|
||||
@@ -53,34 +53,28 @@ func (s *Service) handleAsk(c *gin.Context) {
|
||||
task.SavePath = decision.SavePath
|
||||
token := uuid.New().String()
|
||||
task.Token = token
|
||||
s.transferList.Store(task.ID, task)
|
||||
} else {
|
||||
task.Status = TransferStatusRejected
|
||||
s.transferList.Store(task.ID, task)
|
||||
}
|
||||
c.JSON(http.StatusOK, TransferAskResponse{
|
||||
ID: task.ID,
|
||||
Accepted: decision.Accepted,
|
||||
Token: task.Token,
|
||||
})
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
|
||||
case <-c.Request.Context().Done():
|
||||
// 发送端放弃
|
||||
task.Status = TransferStatusCanceled
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
}
|
||||
}
|
||||
|
||||
// ResolvePendingRequest 外部调用,解决待处理的传输请求
|
||||
// 返回 true 表示成功处理,false 表示未找到该 ID 的请求
|
||||
func (s *Service) ResolvePendingRequest(id string, accept bool, savePath string) bool {
|
||||
val, ok := s.transferList.Load(id)
|
||||
task, ok := s.GetTransfer(id)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
task := val.(Transfer)
|
||||
task.DecisionChan <- Decision{
|
||||
ID: id,
|
||||
Accepted: accept,
|
||||
@@ -91,6 +85,7 @@ func (s *Service) ResolvePendingRequest(id string, accept bool, savePath string)
|
||||
|
||||
// handleUpload 处理接收文件请求
|
||||
func (s *Service) handleUpload(c *gin.Context) {
|
||||
defer s.NotifyTransferListUpdate()
|
||||
id := c.Param("id")
|
||||
token := c.Query("token")
|
||||
|
||||
@@ -104,7 +99,7 @@ func (s *Service) handleUpload(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 获取传输任务
|
||||
val, ok := s.transferList.Load(id)
|
||||
task, ok := s.GetTransfer(id)
|
||||
if !ok {
|
||||
c.JSON(http.StatusUnauthorized, TransferUploadResponse{
|
||||
ID: id,
|
||||
@@ -113,7 +108,6 @@ func (s *Service) handleUpload(c *gin.Context) {
|
||||
})
|
||||
return
|
||||
}
|
||||
task := val.(Transfer)
|
||||
ctx, cancel := context.WithCancel(c.Request.Context())
|
||||
s.cancelMap.Store(task.ID, cancel)
|
||||
defer func() {
|
||||
@@ -143,8 +137,6 @@ func (s *Service) handleUpload(c *gin.Context) {
|
||||
|
||||
// 更新状态为 active
|
||||
task.Status = TransferStatusActive
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
|
||||
savePath := task.SavePath
|
||||
if savePath == "" {
|
||||
@@ -170,21 +162,16 @@ func (s *Service) handleUpload(c *gin.Context) {
|
||||
slog.Error("Failed to create file", "error", err, "component", "transfer")
|
||||
task.Status = TransferStatusError
|
||||
task.ErrorMsg = fmt.Errorf("receiver failed to create file: %v", err).Error()
|
||||
s.transferList.Store(task.ID, task)
|
||||
// 通知前端传输失败
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
s.receive(c, &task, file, ctxReader)
|
||||
s.receive(c, task, file, ctxReader)
|
||||
case ContentTypeText:
|
||||
var buf bytes.Buffer
|
||||
s.receive(c, &task, &buf, ctxReader)
|
||||
s.receive(c, task, &buf, ctxReader)
|
||||
task.Text = buf.String()
|
||||
s.transferList.Store(task.ID, task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
case ContentTypeFolder:
|
||||
s.receiveFolder(c, savePath, &task, ctxReader)
|
||||
s.receiveFolder(c, savePath, task, ctxReader)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,8 +186,8 @@ func (s *Service) receive(c *gin.Context, task *Transfer, writer io.Writer, ctxR
|
||||
Total: total,
|
||||
Speed: speed,
|
||||
}
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
task.Status = TransferStatusActive
|
||||
s.NotifyTransferListUpdate()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -211,8 +198,6 @@ func (s *Service) receive(c *gin.Context, task *Transfer, writer io.Writer, ctxR
|
||||
slog.Info("Sender canceled transfer (Network/Context disconnected)", "id", task.ID, "raw_err", err)
|
||||
task.ErrorMsg = "Sender disconnected"
|
||||
task.Status = TransferStatusCanceled
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -227,8 +212,6 @@ func (s *Service) receive(c *gin.Context, task *Transfer, writer io.Writer, ctxR
|
||||
Message: "File transfer canceled",
|
||||
Status: TransferStatusCanceled,
|
||||
})
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -241,8 +224,6 @@ func (s *Service) receive(c *gin.Context, task *Transfer, writer io.Writer, ctxR
|
||||
slog.Error("Failed to write file", "error", err, "component", "transfer")
|
||||
task.Status = TransferStatusError
|
||||
task.ErrorMsg = fmt.Errorf("failed to write file: %v", err).Error()
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -253,11 +234,11 @@ func (s *Service) receive(c *gin.Context, task *Transfer, writer io.Writer, ctxR
|
||||
})
|
||||
// 传输成功,任务结束
|
||||
task.Status = TransferStatusCompleted
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
}
|
||||
|
||||
func (s *Service) receiveFolder(c *gin.Context, savePath string, task *Transfer, ctxReader io.Reader) {
|
||||
defer s.NotifyTransferListUpdate()
|
||||
|
||||
// 创建根目录
|
||||
destPath := filepath.Join(savePath, task.FileName)
|
||||
if err := os.MkdirAll(destPath, 0755); err != nil {
|
||||
@@ -269,8 +250,6 @@ func (s *Service) receiveFolder(c *gin.Context, savePath string, task *Transfer,
|
||||
slog.Error("Failed to create folder", "error", err, "component", "transfer")
|
||||
task.Status = TransferStatusError
|
||||
task.ErrorMsg = fmt.Errorf("receiver failed to create folder: %v", err).Error()
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -284,8 +263,8 @@ func (s *Service) receiveFolder(c *gin.Context, savePath string, task *Transfer,
|
||||
Total: total,
|
||||
Speed: speed,
|
||||
}
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
task.Status = TransferStatusActive
|
||||
s.NotifyTransferListUpdate()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -298,8 +277,6 @@ func (s *Service) receiveFolder(c *gin.Context, savePath string, task *Transfer,
|
||||
task.Status = TransferStatusCanceled
|
||||
task.ErrorMsg = "Sender disconnected"
|
||||
// 发送端已断开,无需也不应再发送 c.JSON
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -313,8 +290,6 @@ func (s *Service) receiveFolder(c *gin.Context, savePath string, task *Transfer,
|
||||
Message: "File transfer canceled",
|
||||
Status: TransferStatusCanceled,
|
||||
})
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -327,8 +302,6 @@ func (s *Service) receiveFolder(c *gin.Context, savePath string, task *Transfer,
|
||||
Message: fmt.Sprintf("Transfer failed: %v", err),
|
||||
Status: TransferStatusError,
|
||||
})
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -378,6 +351,4 @@ func (s *Service) receiveFolder(c *gin.Context, savePath string, task *Transfer,
|
||||
task.Progress.Total = task.FileSize
|
||||
task.Progress.Current = task.FileSize
|
||||
task.Status = TransferStatusCompleted
|
||||
s.transferList.Store(task.ID, *task)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ type Service struct {
|
||||
savePath string // 默认下载目录
|
||||
|
||||
// pendingRequests 存储等待用户确认的通道
|
||||
// Key: TransferID, Value: Transfer
|
||||
// Key: TransferID, Value: *Transfer
|
||||
transferList sync.Map
|
||||
|
||||
discoveryService *discovery.Service
|
||||
@@ -63,21 +63,21 @@ func (s *Service) Start() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (s *Service) GetTransferList() []Transfer {
|
||||
var requests []Transfer
|
||||
func (s *Service) GetTransferList() []*Transfer {
|
||||
var requests []*Transfer
|
||||
s.transferList.Range(func(key, value any) bool {
|
||||
requests = append(requests, value.(Transfer))
|
||||
requests = append(requests, value.(*Transfer))
|
||||
return true
|
||||
})
|
||||
return requests
|
||||
}
|
||||
|
||||
func (s *Service) GetTransfer(transferID string) (Transfer, bool) {
|
||||
func (s *Service) GetTransfer(transferID string) (*Transfer, bool) {
|
||||
val, ok := s.transferList.Load(transferID)
|
||||
if !ok {
|
||||
return Transfer{}, false
|
||||
return nil, false
|
||||
}
|
||||
return val.(Transfer), true
|
||||
return val.(*Transfer), true
|
||||
}
|
||||
|
||||
func (s *Service) CancelTransfer(transferID string) {
|
||||
@@ -87,8 +87,36 @@ func (s *Service) CancelTransfer(transferID string) {
|
||||
t, ok := s.GetTransfer(transferID)
|
||||
if ok {
|
||||
t.Status = TransferStatusCanceled
|
||||
s.transferList.Store(transferID, t)
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
s.StoreTransferToList(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) StoreTransferToList(transfer *Transfer) {
|
||||
s.transferList.Store(transfer.ID, transfer)
|
||||
s.NotifyTransferListUpdate()
|
||||
}
|
||||
|
||||
func (s *Service) NotifyTransferListUpdate() {
|
||||
s.app.Event.Emit("transfer:refreshList")
|
||||
}
|
||||
|
||||
// CleanTransferList 清理完成的 transfer
|
||||
func (s *Service) CleanTransferList() {
|
||||
s.transferList.Range(func(key, value any) bool {
|
||||
task := value.(*Transfer)
|
||||
if task.Status == TransferStatusCompleted ||
|
||||
task.Status == TransferStatusError ||
|
||||
task.Status == TransferStatusCanceled ||
|
||||
task.Status == TransferStatusRejected {
|
||||
s.transferList.Delete(key)
|
||||
}
|
||||
return true
|
||||
})
|
||||
s.NotifyTransferListUpdate()
|
||||
}
|
||||
|
||||
func (s *Service) DeleteTransfer(transferID string) {
|
||||
s.transferList.Delete(transferID)
|
||||
s.NotifyTransferListUpdate()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user