修复: workspace_root 编译期常量消除+data_dir 运行期+首次授权引导

- 删除 production 中全部 env!("CARGO_MANIFEST_DIR")引用
- workspace_root() 替换为运行期 data_dir(Tauri app_data_dir)
- 相对路径锚定改为 AllowedDirs.first_persistent_dir(),无授权时引导绑定项目
- .trash 迁到 data_dir/.trash,含自动迁移
- authz_debug → temp_dir,workspace_drive → current_dir
- run_command 默认 working_dir 改为空串
- G1 目标刷新改为每次消息覆盖(含 ai_chat_edit 路径)
- #6 评分关键词拆到独立文件 scoring_keywords.rs
- #7 promote 补偿删除 purge_with_descendants → soft_delete
- #8 关联双向同步: 后端事务 sync_related_ids + IPC + 前端全链路
- 设置面板新增数据目录显示
This commit is contained in:
lxy
2026-06-27 21:32:36 +08:00
parent a6d692270f
commit 9c3f27f4ca
26 changed files with 743 additions and 104 deletions
+18 -3
View File
@@ -140,6 +140,21 @@ pub async fn restore_idea(state: State<'_, AppState>, id: String) -> Result<bool
state.ideas.restore(&id).await.map_err(err_str)
}
/// 双向同步关联关系:原子地设置主体灵感的关联目标列表,并自动添加/移除反向关联。
/// 主体灵感 + 所有受影响的关联目标在同一 SQLite 事务中更新,保证原子性。
#[tauri::command]
pub async fn relate_ideas(
state: State<'_, AppState>,
subject_id: String,
target_ids: Vec<String>,
) -> Result<(), String> {
state
.ideas
.sync_related_ids(&subject_id, &target_ids)
.await
.map_err(err_str)
}
/// 列出回收站灵感(deleted_at IS NOT NULL,按更新时间降序)。对标 list_deleted_projects。
#[tauri::command]
pub async fn list_deleted_ideas(state: State<'_, AppState>) -> Result<Vec<IdeaRecord>, String> {
@@ -199,10 +214,10 @@ pub async fn promote_idea(
..record
};
if let Err(e) = state.ideas.update_full(&updated).await {
// 回写失败:补偿删已建项目,避免悬空项目(idea.promoted_to 仍空,可重试立项)
// 回写失败:补偿删已建项目(进回收站,可恢复),避免悬空项目(idea.promoted_to 仍空,可重试立项)
tracing::error!("灵感 {id} 回写失败,补偿删除已建项目 {project_id}: {e}");
if let Err(del_err) = state.projects.purge_with_descendants(&project_id).await {
tracing::error!("补偿删项目 {project_id} 也失败(需人工清理): {del_err}");
if let Err(del_err) = state.projects.soft_delete(&project_id).await {
tracing::error!("补偿删项目 {project_id} 也失败(需人工清理): {del_err}");
}
return Err(format!("灵感立项回写失败(已回滚项目创建): {}", e));
}