修复: 文件系统初始化守卫与传输收尾等七处
- filesystemSvc 守卫17绑定方法,异步初始化完成前返回明确错误 - MovePath 跨盘剪切建 move emitter,失败清理目标盘残留 - SFTP 空目录下载/上传补 MkdirAll 落地 - drawio 下载失败等待者立即返回,不再空轮询30分钟 - batch 高亮补 %1 与 %%i 规则 - 错误文案转换抽 errMessage 共享函数,11处归一 - log.Printf 统一 slog.Warn
This commit is contained in:
@@ -67,6 +67,13 @@ func EnsureDrawioViewer(progress service.DownloadProgress) error {
|
||||
if isDrawioViewerReady() {
|
||||
return nil
|
||||
}
|
||||
// 首个下载方已退出仍未就绪(下载失败),等待者立即失败而非空轮询到超时
|
||||
drawioEnsureMu.Lock()
|
||||
ensuring := drawioEnsuring
|
||||
drawioEnsureMu.Unlock()
|
||||
if !ensuring {
|
||||
return fmt.Errorf("drawio viewer 下载失败,请重试")
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
return fmt.Errorf("等待 drawio viewer 下载超时")
|
||||
|
||||
@@ -552,7 +552,8 @@ func (s *FileSystemService) CopyPath(src, dst string, onProgress func(copied, to
|
||||
}
|
||||
|
||||
// MovePath 移动文件或目录:同盘直接重命名,跨盘回退为复制后永久删除源(不走回收站)
|
||||
func (s *FileSystemService) MovePath(src, dst string) error {
|
||||
// 跨盘复制阶段经 onProgress 回调进度(可为 nil),同盘 rename 无进度
|
||||
func (s *FileSystemService) MovePath(src, dst string, onProgress func(copied, total int64)) error {
|
||||
info, err := s.checkCopyMovePaths(src, dst)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -564,8 +565,9 @@ func (s *FileSystemService) MovePath(src, dst string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 跨盘:复制 + 删除源
|
||||
if err := s.CopyPath(src, dst, nil); err != nil {
|
||||
// 跨盘:复制 + 删除源;复制中途失败清理 dst 残留,否则重试会因目标已存在被拒
|
||||
if err := s.CopyPath(src, dst, onProgress); err != nil {
|
||||
_ = os.RemoveAll(dst)
|
||||
return err
|
||||
}
|
||||
if err := os.RemoveAll(src); err != nil {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -851,7 +851,7 @@ func supplementDir(c oss.OSSProvider, ctx context.Context, remoteDir string, tmp
|
||||
continue
|
||||
}
|
||||
if count >= common.MaxSupplementFiles {
|
||||
log.Printf("[站点下载] 补充扫描达到上限: count=%d", common.MaxSupplementFiles)
|
||||
slog.Warn("站点下载补充扫描达到上限", "count", common.MaxSupplementFiles)
|
||||
return
|
||||
}
|
||||
localPath := filepath.Join(tmpDir, filepath.FromSlash(f.Key))
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"io"
|
||||
"io/fs"
|
||||
@@ -539,7 +538,7 @@ func sftpSupplementDir(s *Service, c *Client, remoteDir string, tmpDir string, s
|
||||
continue
|
||||
}
|
||||
if count >= common.MaxSupplementFiles {
|
||||
log.Printf("[站点下载] 补充扫描达到上限: count=%d", common.MaxSupplementFiles)
|
||||
slog.Warn("站点下载补充扫描达到上限", "count", common.MaxSupplementFiles)
|
||||
break
|
||||
}
|
||||
fullPath := path.Join(remoteDir, entry.Name())
|
||||
@@ -617,6 +616,10 @@ func (s *Service) DownloadToFile(connID, remotePath, localDstDir string, onProgr
|
||||
if err := walk(remotePath, dstDir); err != nil {
|
||||
return "", fmt.Errorf("遍历远程目录失败: %w", err)
|
||||
}
|
||||
// 空目录时清单为空,downloadFileTo 不会执行,目标目录须显式创建
|
||||
if err := os.MkdirAll(dstDir, 0755); err != nil {
|
||||
return "", fmt.Errorf("创建本地目录失败: %w", err)
|
||||
}
|
||||
|
||||
var copied int64
|
||||
for _, e := range entries {
|
||||
@@ -714,6 +717,12 @@ func (s *Service) UploadFromFile(connID, localPath, remoteDir string, onProgress
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 空目录时文件清单为空,uploadFileTo 不会执行,远端根目录须显式创建
|
||||
if err := c.WithRetry(func(sc *sftpclient.Client) error {
|
||||
return sc.MkdirAll(remoteRoot)
|
||||
}); err != nil {
|
||||
return fmt.Errorf("创建远程目录失败: %w", err)
|
||||
}
|
||||
var copied int64
|
||||
for _, f := range files {
|
||||
if err := s.uploadFileTo(c, f.local, path.Join(remoteRoot, f.rel), &copied, total, onProgress); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user