From b4661072366c4dcc63e914f2ec8625ad73b14645 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 5 Jan 2026 15:10:18 +0800 Subject: Add RejectAll mode for share merging and fix share ID trimming - Add ShareMergeMode::RejectAll variant to reject all incoming shares - Trim server suffix from share IDs when updating local sheet info - Sign vault as modified after successful share mapping merge - Fix get_current_sheet_name call to use correct parameter value --- crates/vcs_actions/src/actions/local_actions.rs | 10 ++++-- crates/vcs_actions/src/actions/sheet_actions.rs | 8 ++++- crates/vcs_data/src/data/vault/sheet_share.rs | 48 +++++++++++++++---------- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/crates/vcs_actions/src/actions/local_actions.rs b/crates/vcs_actions/src/actions/local_actions.rs index 1f764c9..53a1ff8 100644 --- a/crates/vcs_actions/src/actions/local_actions.rs +++ b/crates/vcs_actions/src/actions/local_actions.rs @@ -13,7 +13,8 @@ use serde::{Deserialize, Serialize}; use tcp_connection::error::TcpTargetError; use vcs_data::{ constants::{ - CLIENT_PATH_CACHED_SHEET, CLIENT_PATH_LOCAL_SHEET, REF_SHEET_NAME, VAULT_HOST_NAME, + CLIENT_PATH_CACHED_SHEET, CLIENT_PATH_LOCAL_SHEET, REF_SHEET_NAME, + SERVER_SUFFIX_SHEET_SHARE_FILE, VAULT_HOST_NAME, }, data::{ local::{ @@ -172,7 +173,7 @@ pub async fn update_to_latest_info_action( for sheet in vault.sheets().await? { // Build share parts if let Some(holder) = sheet.holder() { - if holder == &member_id { + if holder == &member_id || holder == VAULT_HOST_NAME { let mut sheet_shares: HashMap = HashMap::new(); for share in sheet.get_shares().await? { // Get SharePath @@ -183,7 +184,10 @@ pub async fn update_to_latest_info_action( let Some(share_id) = share_path.file_name() else { continue; }; - sheet_shares.insert(share_id.display().to_string(), share); + let share_id = share_id.display().to_string(); + let share_id_trimed = + share_id.trim_end_matches(SERVER_SUFFIX_SHEET_SHARE_FILE); + sheet_shares.insert(share_id_trimed.to_string(), share); } shares_in_my_sheets.insert(sheet.name().clone(), sheet_shares); } diff --git a/crates/vcs_actions/src/actions/sheet_actions.rs b/crates/vcs_actions/src/actions/sheet_actions.rs index 759c275..7c63a2f 100644 --- a/crates/vcs_actions/src/actions/sheet_actions.rs +++ b/crates/vcs_actions/src/actions/sheet_actions.rs @@ -400,7 +400,7 @@ pub async fn share_mapping_action( // Check sheet let sheet_name = args.from_sheet.unwrap_or( - get_current_sheet_name(&ctx, instance, &member_id, false) + get_current_sheet_name(&ctx, instance, &member_id, true) .await? .0, ); @@ -569,6 +569,12 @@ pub async fn merge_share_mapping_action( .await .read::() .await?; + match result { + MergeShareMappingActionResult::Success => { + sign_vault_modified(true).await; + } + _ => {} + } return Ok(result); } diff --git a/crates/vcs_data/src/data/vault/sheet_share.rs b/crates/vcs_data/src/data/vault/sheet_share.rs index aa72283..1e692f1 100644 --- a/crates/vcs_data/src/data/vault/sheet_share.rs +++ b/crates/vcs_data/src/data/vault/sheet_share.rs @@ -58,6 +58,9 @@ pub enum ShareMergeMode { /// Pre-check for conflicts, prohibit merging if any conflicts are found #[default] Safe, + + /// Reject all shares + RejectAll, } #[derive(Default, Serialize, Deserialize, ConfigFile, Clone)] @@ -168,13 +171,14 @@ impl<'a> Sheet<'a> { let mut copy_sheet = self.clone_data(); // Pre-check - let precheck = self.precheck(©_share); + let conflicts = self.precheck(©_share); + let mut reject_mode = false; match share_merge_mode { // Safe mode: conflicts are not allowed ShareMergeMode::Safe => { // Conflicts found - if !precheck.ok() { + if !conflicts.ok() { // Do nothing, return Error return Err(Error::new( std::io::ErrorKind::AlreadyExists, @@ -185,7 +189,7 @@ impl<'a> Sheet<'a> { // Overwrite mode: when conflicts occur, prioritize the share item ShareMergeMode::Overwrite => { // Handle duplicate mappings - for path in precheck.duplicate_mapping { + for path in conflicts.duplicate_mapping { // Get the share data let Some(share_value) = copy_share.mappings.remove(&path) else { return Err(Error::new( @@ -198,7 +202,7 @@ impl<'a> Sheet<'a> { } // Handle duplicate IDs - for path in precheck.duplicate_file { + for path in conflicts.duplicate_file { // Get the share data let Some(share_value) = copy_share.mappings.remove(&path) else { return Err(Error::new( @@ -240,30 +244,36 @@ impl<'a> Sheet<'a> { // Skip mode: when conflicts occur, prioritize the local sheet ShareMergeMode::Skip => { // Directly remove conflicting items - for path in precheck.duplicate_mapping { + for path in conflicts.duplicate_mapping { copy_share.mappings.remove(&path); } - for path in precheck.duplicate_file { + for path in conflicts.duplicate_file { copy_share.mappings.remove(&path); } } + // Reject all mode: reject all shares + ShareMergeMode::RejectAll => { + reject_mode = true; // Only mark as rejected + } } - // Subsequent merging - copy_sheet - .mapping_mut() - .extend(copy_share.mappings.into_iter()); + if !reject_mode { + // Subsequent merging + copy_sheet + .mapping_mut() + .extend(copy_share.mappings.into_iter()); - // Merge completed - self.data = copy_sheet; // Write the result + // Merge completed + self.data = copy_sheet; // Write the result - // Merge completed, consume the sheet - self.persist().await.map_err(|err| { - Error::new( - std::io::ErrorKind::NotFound, - format!("Write sheet failed: {}", err), - ) - })?; + // Merge completed, consume the sheet + self.persist().await.map_err(|err| { + Error::new( + std::io::ErrorKind::NotFound, + format!("Write sheet failed: {}", err), + ) + })?; + } // Persistence succeeded, continue to consume the share item share.remove().await.map_err(|err| { -- cgit