feat(organize): separate source dir from destination dir (从源目录整理到目的地目录)

Previously organize only exposed a single 'target dir' that was actually
the destination, conflating 源目录 (where files to organize live) with
目的地目录 (where organized files go). Add an explicit source directory:

- OrganizeOptions gains SourcePath; DestPath replaces the old TargetPath
  (destination) for clarity. New organize.source_dir setting + source_path
  request override; resolveSourceRoot falls back to library path.
- OrganizeLibraryWithOptions only organizes media located under the source
  root, so operators can point at a specific download/staging folder and
  organize into a distinct destination.
- Handler accepts source_path/dest_path (target_path kept as a deprecated
  alias for the destination, backward compatible).
- Settings page splits into 整理源目录(待整理) + 整理目的地目录; Tools organize
  panel exposes 源目录 + 目的地目录 inputs with clear copy.

Defaults are unchanged (source = destination = library path) so existing
setups behave identically. Adds a regression test that organize is scoped
to the source directory.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
soldosluka857
2026-05-30 04:43:35 +00:00
committed by Shuke
parent b2ccd04844
commit 8f0c6d2324
6 changed files with 175 additions and 23 deletions
+11 -4
View File
@@ -152,10 +152,17 @@ const GROUPS: SettingGroup[] = [
hint: '根据元数据(语言/国家/类型)自动分类到子目录(如:华语电影、欧美剧、日番)',
},
{
key: 'organize.target_dir',
label: '整理目标目录',
key: 'organize.source_dir',
label: '整理源目录(待整理)',
type: 'text',
hint: '留空则默认整理到各媒体库对应路径(见下方参考)',
hint: '从该目录读取待整理文件;留空则默认整理整个媒体库(媒体库路径)。',
placeholder: '/mnt/downloads',
},
{
key: 'organize.target_dir',
label: '整理目的地目录',
type: 'text',
hint: '整理后输出到该目录;留空则默认整理到各媒体库对应路径(见下方参考)。与「源目录」相互独立。',
placeholder: '/mnt/media/organized',
},
{
@@ -388,7 +395,7 @@ export function SettingsPage() {
<div className="glass-panel">
<div className="mb-3 flex items-center gap-2 text-sm text-ink-100">
<FolderOpen size={16} className="text-brand-500" />
<span>默认整理路径参考(未设目标目录时按媒体库归类)</span>
<span>默认整理路径参考(未设目的地目录时按媒体库归类)</span>
</div>
<table className="w-full text-left text-sm">
<thead className="text-xs uppercase tracking-wider text-sand-500">