fix: Add parent_id to all nodes in scan system

Problem:
- All nodes (files and folders) had NULL parent_id
- Tree structure was flat (no hierarchy)
- Could not display proper folder tree

Solution:
- Add Home folder as root node
- Map folder paths to node_ids (folder_id_map)
- Set parent_id for all folders (point to parent folder's node_id)
- Set parent_id for all files (point to containing folder's node_id)
- Root directory files/folders point to Home folder

Result:
- Folders: 802 (801 + Home root)
- Files: 11857
- Total nodes: 12659
- Nodes with parent_id: 12658 (100%)
- Tree structure fully functional 

Files:
- src/scan.rs (fixed parent_id logic)
This commit is contained in:
Warren
2026-05-17 03:26:15 +08:00
parent 6b11e8fa41
commit 86fa66bb42
2 changed files with 58 additions and 10 deletions

Binary file not shown.

View File

@@ -65,15 +65,56 @@ pub fn scan_directory(user_id: &str, dir: &str, batch_size: usize, options: Scan
let mut file_nodes: Vec<FileNode> = Vec::new();
let mut file_info: Vec<(String, String)> = Vec::new();
for (path_str, label, parent_id) in &folders {
let mtime = fs::metadata(path_str)
.and_then(|m| m.modified())
.unwrap_or(std::time::SystemTime::UNIX_EPOCH);
let mtime_secs = mtime.duration_since(std::time::SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
let mac_str = get_mac_address()?;
let root_node_id = generate_uuid(&dir_path.to_string_lossy(), "Home", &mac_str, chrono::Utc::now().timestamp() as u64);
folder_nodes.push(FileNode {
node_id: root_node_id.clone(),
label: "Home".to_string(),
aliases: Aliases::empty(),
file_uuid: None,
sha256: None,
parent_id: None,
children: Vec::new(),
node_type: NodeType::Folder,
icon: Some("🏠".to_string()),
color: None,
bg_color: None,
file_size: None,
registered_at: None,
created_at: chrono::Utc::now().timestamp().to_string(),
updated_at: chrono::Utc::now().timestamp().to_string(),
sort_order: 0,
});
let folder_id_map: HashMap<String, String> = {
let mut map = HashMap::new();
map.insert(dir_path.to_string_lossy().to_string(), root_node_id.clone());
let node_id = generate_uuid(path_str, label, &mac, mtime_secs);
for (path_str, label, _parent_path) in &folders {
let mtime = fs::metadata(path_str)
.and_then(|m| m.modified())
.unwrap_or(std::time::SystemTime::UNIX_EPOCH);
let mtime_secs = mtime.duration_since(std::time::SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
let node_id = generate_uuid(path_str, label, &mac_str, mtime_secs);
map.insert(path_str.clone(), node_id);
}
map
};
for (path_str, label, parent_path) in &folders {
let node_id = folder_id_map.get(path_str).cloned().unwrap();
let parent_node_id = if let Some(ref parent_p) = parent_path {
folder_id_map.get(parent_p).cloned()
} else {
Some(root_node_id.clone())
};
folder_nodes.push(FileNode {
node_id,
@@ -81,7 +122,7 @@ pub fn scan_directory(user_id: &str, dir: &str, batch_size: usize, options: Scan
aliases: Aliases::empty(),
file_uuid: None,
sha256: None,
parent_id: parent_id.clone(),
parent_id: parent_node_id,
children: Vec::new(),
node_type: NodeType::Folder,
icon: Some("📁".to_string()),
@@ -107,6 +148,13 @@ pub fn scan_directory(user_id: &str, dir: &str, batch_size: usize, options: Scan
file_info.push((node_id.clone(), path_str.clone()));
let file_dir = Path::new(path_str).parent().unwrap_or(dir_path);
let parent_node_id = if file_dir == dir_path {
Some(root_node_id.clone())
} else {
folder_id_map.get(file_dir.to_string_lossy().as_ref()).cloned()
};
file_nodes.push(FileNode {
node_id,
label: filename.clone(),
@@ -117,7 +165,7 @@ pub fn scan_directory(user_id: &str, dir: &str, batch_size: usize, options: Scan
},
file_uuid: None,
sha256: None,
parent_id: find_parent_folder(path_str, dir_path, &folders),
parent_id: parent_node_id,
children: Vec::new(),
node_type: NodeType::File,
icon: get_file_icon(filename),