新增: 项目文件浏览器(文件树+内容预览+Git 状态标记)
项目详情页新增文件标签页,用户可在 DevFlow 内浏览项目 文件,查看文件内容和 Git 改动状态,无需切换外部编辑器。 后端接口: - 文件树查询:列工程目录,合并 Git 状态到每个文件 (噪音过滤 node_modules/target/.git 等,路径穿越防御) - 文件读取:支持文本/图片/二进制检测,1MB 上限 前端组件: - 文件树:递归树形展示,懒加载子目录,Git 状态标记 (橙色=已修改/绿色=已新增/灰色=未跟踪) - 文件预览:代码文本/图片/二进制三分支 - 主容器:工程选择(单工程隐藏)+ 面包屑导航 + 刷新 界面文案中英文同步补齐。
This commit is contained in:
107
src/api/module.ts
Normal file
107
src/api/module.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
//! 工程系统 API — IPC invoke 封装(对标设计 §五工程系统 + Batch 10 文件浏览)
|
||||
//
|
||||
// 工程记录类型复用 df-storage::ProjectModuleRecord(字段一一对应)。
|
||||
// 文件浏览(getModuleFileTree/readModuleFile)返回 serde_json::Value,前端按字段取用。
|
||||
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
/** 工程记录(对齐后端 df_storage::models::ProjectModuleRecord)。 */
|
||||
export interface ProjectModuleRecord {
|
||||
id: string
|
||||
project_id: string
|
||||
name: string
|
||||
/** 工程目录绝对路径(本机) */
|
||||
path: string
|
||||
git_url: string | null
|
||||
/** 技术栈 JSON 字符串 */
|
||||
stack: string | null
|
||||
auto_detected: boolean
|
||||
sort_order: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
/** 文件树单条目(单层;前端点击文件夹再懒加载下一层)。 */
|
||||
export interface FileTreeEntry {
|
||||
/** 文件/目录名(不含路径) */
|
||||
name: string
|
||||
/** 相对工程根的路径(POSIX 风格,前端用作后续 sub_path / file_path) */
|
||||
path: string
|
||||
is_dir: boolean
|
||||
/** 字节数(文件夹恒为 0) */
|
||||
size: number
|
||||
/** Git 状态码(`git status --porcelain` 的 XY 两字符,如 " M"/"M "/"??");文件夹恒无 */
|
||||
git_status?: string
|
||||
}
|
||||
|
||||
/** getModuleFileTree 返回结构。 */
|
||||
export interface FileTreeResult {
|
||||
/** 相对工程根的当前目录路径(根目录为空串) */
|
||||
path: string
|
||||
entries: FileTreeEntry[]
|
||||
}
|
||||
|
||||
/** readModuleFile 返回结构。 */
|
||||
export interface ReadFileResult {
|
||||
path: string
|
||||
/** 文本内容(二进制文件为空串) */
|
||||
content: string
|
||||
/** 文件总字节数 */
|
||||
size: number
|
||||
is_binary: boolean
|
||||
/** 是否因超 1MB 被截断 */
|
||||
truncated: boolean
|
||||
}
|
||||
|
||||
/** Git 改动文件项(对齐后端 GitChangedFile)。 */
|
||||
export interface GitChangedFile {
|
||||
status: string
|
||||
path: string
|
||||
}
|
||||
|
||||
/** 最近提交项(对齐后端 GitRecentCommit)。 */
|
||||
export interface GitRecentCommit {
|
||||
hash: string
|
||||
subject: string
|
||||
}
|
||||
|
||||
/** getModuleGitStatus 返回结构。 */
|
||||
export interface GitStatusResult {
|
||||
branch: string
|
||||
changed_files: GitChangedFile[]
|
||||
recent_commits: GitRecentCommit[]
|
||||
is_git_repo: boolean
|
||||
}
|
||||
|
||||
export const moduleApi = {
|
||||
/** 列出项目全部工程(按 sort_order ASC)。 */
|
||||
listProjectModules(projectId: string): Promise<ProjectModuleRecord[]> {
|
||||
return invoke('list_project_modules', { projectId })
|
||||
},
|
||||
|
||||
/** 查询工程 Git 状态(分支/改动文件/最近提交;非 git 仓库返回 is_git_repo:false)。 */
|
||||
getModuleGitStatus(moduleId: string): Promise<GitStatusResult> {
|
||||
return invoke('get_module_git_status', { moduleId })
|
||||
},
|
||||
|
||||
/**
|
||||
* 列出工程文件树(单层 + git 状态合并)。
|
||||
* @param moduleId 工程 id
|
||||
* @param subPath 相对工程根的子路径(钻入子目录);省略/空 = 工程根
|
||||
*/
|
||||
getModuleFileTree(moduleId: string, subPath?: string): Promise<FileTreeResult> {
|
||||
return invoke('get_module_file_tree', {
|
||||
moduleId,
|
||||
subPath: subPath && subPath.length > 0 ? subPath : null,
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 读工程内单文件(文本/图片;1MB 上限,二进制检测)。
|
||||
* @param moduleId 工程 id
|
||||
* @param filePath 相对工程根的文件路径(POSIX 风格)
|
||||
*/
|
||||
readModuleFile(moduleId: string, filePath: string): Promise<ReadFileResult> {
|
||||
return invoke('read_module_file', { moduleId, filePath })
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user