优化: 所有剩余UI/UX待办一批完成(持久化+AuditLog+解耦+total+原12大改+P2)
持久化(P1-c):新建 usePersistedRef composable,Tasks/AuditLog/ProjectDetail 等接入 localStorage
AuditLog(P1-d):后端 list_tool_executions 加 WHERE 筛选+返 {items,total,has_more},前端对接+长列折叠+筛选持久化
数据源解耦(P1-g):ProjectDetail projectTasks 按 project_id 独立加载 + ChatInput @项目联想独立加载(不读 store.tasks 当前页)
GitChanges(12a):后端 get_module_commits 加 git rev-list --count 返 total,前端显真实总数
原12大改:Dashboard 统计卡压底行(1)/Projects 列表卡片视图(2)/project_event 埋点排序(3)/TaskDetail 重设计(4)/IdeaDetail 重设计(5)/KnowledgeDetail 重设计(6)/界面持久化+侧栏Ctrl+B+审批数字键(7)/ProjectDetail 三栏改两栏(10)
P2打磨:文件浏览器(FileTree去重/FilePreview行号.md Diff/selectedFilePath归位)/settings反馈(假保存/端口校验)/AI会话(try-catch/scrollIntoView)/后端计数(move_queue事件/timeline total/workflow分页/import_batch分块)/杂项(TopBar/ConfirmDialog键盘/CIStatus i18n/ToolResultBody/ModuleNode/ApprovalDialog全选)
This commit is contained in:
@@ -279,6 +279,9 @@ struct GitStatus {
|
||||
changed_files: Vec<GitChangedFile>,
|
||||
/// 最近 10 条提交
|
||||
recent_commits: Vec<GitRecentCommit>,
|
||||
/// 当前 HEAD 的全量提交数(`git rev-list --count HEAD`)。
|
||||
/// 前端历史 Tab 徽标 / 分支栏计数用它,而非 recent_commits.len()(后者受分页限制)。
|
||||
total_commits: i64,
|
||||
/// 该目录是否为 Git 仓库(无 .git 时 false,其余字段空)
|
||||
is_git_repo: bool,
|
||||
}
|
||||
@@ -289,6 +292,7 @@ fn empty_status() -> GitStatus {
|
||||
branch: String::new(),
|
||||
changed_files: Vec::new(),
|
||||
recent_commits: Vec::new(),
|
||||
total_commits: 0,
|
||||
is_git_repo: false,
|
||||
}
|
||||
}
|
||||
@@ -447,10 +451,19 @@ fn run_git_status(dir: &str) -> GitStatus {
|
||||
}
|
||||
}
|
||||
|
||||
// 4) 全量提交计数:`git rev-list --count HEAD`(供前端历史 Tab 徽标真实总数,
|
||||
// 非 recent_commits.len() 后者上限 50)。命令失败 → 退化为 recent_commits 长度。
|
||||
let total_commits = run_git_cmd(path, &["rev-list", "--count", "HEAD"], timeout)
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| !s.is_empty())
|
||||
.and_then(|s| s.parse::<i64>().ok())
|
||||
.unwrap_or(recent_commits.len() as i64);
|
||||
|
||||
GitStatus {
|
||||
branch,
|
||||
changed_files,
|
||||
recent_commits,
|
||||
total_commits,
|
||||
is_git_repo: true,
|
||||
}
|
||||
}
|
||||
@@ -949,7 +962,8 @@ fn collect_git_status_map(dir: &str) -> HashMap<String, String> {
|
||||
}
|
||||
|
||||
/// 查询工程 Git 提交历史(分页,按时间倒序)。
|
||||
/// 返回 { commits: [{ hash, subject, timestamp }], has_more: bool }。
|
||||
/// 返回 { commits: [{ hash, subject, timestamp, author }], has_more: bool, total: i64 }。
|
||||
/// total = `git rev-list --count HEAD` 的全量提交数,供前端徽标真实总数(commits.len() 受分页限制)。
|
||||
#[tauri::command]
|
||||
pub async fn get_module_commits(
|
||||
state: State<'_, AppState>,
|
||||
@@ -969,7 +983,7 @@ pub async fn get_module_commits(
|
||||
.ok_or_else(|| format!("工程 {module_id} 不存在"))?;
|
||||
let path = std::path::Path::new(&module.path);
|
||||
if !path.join(".git").exists() {
|
||||
return Ok(serde_json::json!({ "commits": [], "has_more": false }));
|
||||
return Ok(serde_json::json!({ "commits": [], "has_more": false, "total": 0 }));
|
||||
}
|
||||
let skip = skip.unwrap_or(0);
|
||||
let fetch = limit.unwrap_or(50);
|
||||
@@ -978,16 +992,18 @@ pub async fn get_module_commits(
|
||||
let dir = module.path.clone();
|
||||
let dir_for_git = dir.clone();
|
||||
// git 命令在 spawn_blocking 中执行(阻塞 IO 不污染 async runtime),10s 超时
|
||||
let commits: Vec<serde_json::Value> = tokio::task::spawn_blocking(move || -> Vec<serde_json::Value> {
|
||||
let (commits, total): (Vec<serde_json::Value>, i64) = tokio::task::spawn_blocking(move || -> (Vec<serde_json::Value>, i64) {
|
||||
let path = std::path::Path::new(&dir_for_git);
|
||||
let timeout = std::time::Duration::from_secs(10);
|
||||
let out = run_git_cmd(
|
||||
std::path::Path::new(&dir_for_git),
|
||||
path,
|
||||
&[
|
||||
"log",
|
||||
&format!("--skip={}", skip),
|
||||
&format!("-{}", fetch_plus),
|
||||
"--format=%h %ct %an %s",
|
||||
],
|
||||
std::time::Duration::from_secs(10),
|
||||
timeout,
|
||||
)
|
||||
.unwrap_or_default();
|
||||
let mut commits: Vec<serde_json::Value> = Vec::new();
|
||||
@@ -1010,7 +1026,14 @@ pub async fn get_module_commits(
|
||||
}));
|
||||
}
|
||||
}
|
||||
commits
|
||||
// 全量提交计数(`git rev-list --count HEAD`):前端历史 Tab 徽标真实总数。
|
||||
// 命令失败 → 退化为 0(前端会显示 0,但 has_more 仍可驱动分页)。
|
||||
let total = run_git_cmd(path, &["rev-list", "--count", "HEAD"], timeout)
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| !s.is_empty())
|
||||
.and_then(|s| s.parse::<i64>().ok())
|
||||
.unwrap_or(0);
|
||||
(commits, total)
|
||||
})
|
||||
.await
|
||||
.map_err(|e| format!("提交历史查询任务失败: {e}"))?;
|
||||
@@ -1023,6 +1046,7 @@ pub async fn get_module_commits(
|
||||
Ok(serde_json::json!({
|
||||
"commits": returned,
|
||||
"has_more": has_more,
|
||||
"total": total,
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user