feat(scan): 添加自定义扫描目录选择功能
- 在扫描页面添加目录输入框和选择按钮 - 实现文件系统浏览器,支持Windows盘符和目录浏览 - 添加扫描目录参数传递到后端服务 - 显示当前扫描目录路径信息 - 修复前端空数组访问错误 - 更新文档说明扫描功能变化
This commit is contained in:
+32
-10
@@ -34,6 +34,7 @@ type ScanStatus struct {
|
||||
Message string `json:"message"` // 简要说明
|
||||
Started string `json:"started"` // 开始时间
|
||||
Elapsed int64 `json:"elapsed"` // 已运行秒数
|
||||
RootDir string `json:"rootDir"` // 本次扫描的根目录
|
||||
Lines []string `json:"lines"` // 运行日志
|
||||
}
|
||||
|
||||
@@ -44,6 +45,7 @@ type ScanService struct {
|
||||
state ScanState
|
||||
msg string
|
||||
started time.Time
|
||||
rootDir string
|
||||
lines []string
|
||||
}
|
||||
|
||||
@@ -52,20 +54,26 @@ func NewScanService(st *store.Store) *ScanService {
|
||||
return &ScanService{store: st, state: ScanIdle}
|
||||
}
|
||||
|
||||
// Start 启动一次扫描整理;已在运行时返回错误
|
||||
func (s *ScanService) Start() error {
|
||||
// Start 启动一次扫描整理;已在运行时返回错误。rootDir 为空时默认扫描当前运行目录。
|
||||
func (s *ScanService) Start(rootDir string) error {
|
||||
s.mu.Lock()
|
||||
if s.state == ScanRunning {
|
||||
s.mu.Unlock()
|
||||
return errors.New("扫描整理正在运行中,请等待完成")
|
||||
}
|
||||
rootDir = resolveRootDir(rootDir)
|
||||
if st, err := os.Stat(rootDir); err != nil || !st.IsDir() {
|
||||
s.mu.Unlock()
|
||||
return fmt.Errorf("扫描目录不存在或不可访问: %s", rootDir)
|
||||
}
|
||||
s.state = ScanRunning
|
||||
s.msg = ""
|
||||
s.started = time.Now()
|
||||
s.rootDir = rootDir
|
||||
s.lines = nil
|
||||
s.mu.Unlock()
|
||||
|
||||
go s.run()
|
||||
go s.run(rootDir)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -82,12 +90,29 @@ func (s *ScanService) Status() ScanStatus {
|
||||
Message: s.msg,
|
||||
Started: s.started.Format("2006-01-02 15:04:05"),
|
||||
Elapsed: elapsed,
|
||||
RootDir: s.rootDir,
|
||||
Lines: append([]string{}, s.lines...),
|
||||
}
|
||||
}
|
||||
|
||||
// resolveRootDir 解析扫描根目录:空值回退当前工作目录,并做绝对路径归一化
|
||||
func resolveRootDir(dir string) string {
|
||||
if strings.TrimSpace(dir) == "" {
|
||||
wd, err := os.Getwd()
|
||||
if err == nil {
|
||||
return wd
|
||||
}
|
||||
return "."
|
||||
}
|
||||
abs, err := filepath.Abs(strings.TrimSpace(dir))
|
||||
if err != nil {
|
||||
return strings.TrimSpace(dir)
|
||||
}
|
||||
return abs
|
||||
}
|
||||
|
||||
// run 后台执行:捕获 stdout 日志流式写入 lines,结束后更新状态
|
||||
func (s *ScanService) run() {
|
||||
func (s *ScanService) run(rootDir string) {
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
s.finish(ScanError, "创建日志管道失败: "+err.Error())
|
||||
@@ -112,7 +137,7 @@ func (s *ScanService) run() {
|
||||
}
|
||||
}()
|
||||
|
||||
scanErr := s.runScan()
|
||||
scanErr := s.runScan(rootDir)
|
||||
|
||||
os.Stdout = oldStdout
|
||||
_ = w.Close()
|
||||
@@ -144,12 +169,9 @@ func sanitizeLine(line string) string {
|
||||
}
|
||||
|
||||
// runScan 执行完整整理流程:扫描 → 过滤 → 释放解码器 → 归类 → 移动
|
||||
func (s *ScanService) runScan() error {
|
||||
rootDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取当前路径异常: %v", err)
|
||||
}
|
||||
func (s *ScanService) runScan(rootDir string) error {
|
||||
pickerDir := filepath.Join(rootDir, filepath.Base(rootDir)+"-picker")
|
||||
fmt.Printf("=== 扫描根目录: %s \n", rootDir)
|
||||
fmt.Printf("=== 整理输出目录(白名单): %s \n", pickerDir)
|
||||
|
||||
res, err := scanner.Scan(scanner.Options{
|
||||
|
||||
Reference in New Issue
Block a user