feat: 实现文件浏览器功能
- 添加 /api/files 路由支持目录浏览和文件读取 - 支持 list、read、stat、tree 四个端点 - 安全路径检查防止目录遍历攻击 - 创建 FileBrowser React 组件 - 支持目录导航、文件预览、隐藏文件切换 - 在 Web UI 中添加可切换的文件浏览面板
This commit is contained in:
@@ -94,3 +94,70 @@ export function createWebSocket(sessionId: string): WebSocket {
|
||||
const host = window.location.host;
|
||||
return new WebSocket(`${protocol}//${host}/api/ws/${sessionId}`);
|
||||
}
|
||||
|
||||
// Files
|
||||
export interface FileInfo {
|
||||
name: string;
|
||||
path: string;
|
||||
type: 'file' | 'directory';
|
||||
size: number;
|
||||
modified: string;
|
||||
extension?: string;
|
||||
}
|
||||
|
||||
export interface FileListResponse {
|
||||
success: boolean;
|
||||
data: {
|
||||
path: string;
|
||||
absolutePath: string;
|
||||
parent: string | null;
|
||||
files: FileInfo[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface FileReadResponse {
|
||||
success: boolean;
|
||||
data: {
|
||||
path: string;
|
||||
name: string;
|
||||
type: string;
|
||||
size: number;
|
||||
modified: string;
|
||||
content: string;
|
||||
encoding: 'utf-8' | 'base64';
|
||||
};
|
||||
}
|
||||
|
||||
export interface FileTreeNode {
|
||||
name: string;
|
||||
path: string;
|
||||
type: 'file' | 'directory';
|
||||
children?: FileTreeNode[];
|
||||
}
|
||||
|
||||
export interface FileTreeResponse {
|
||||
success: boolean;
|
||||
data: {
|
||||
path: string;
|
||||
tree: FileTreeNode[];
|
||||
};
|
||||
}
|
||||
|
||||
export async function getWorkingDirectory(): Promise<{ success: boolean; data: { workingDirectory: string; separator: string } }> {
|
||||
return request('GET', '/files');
|
||||
}
|
||||
|
||||
export async function listFiles(path: string = '.', showHidden: boolean = false): Promise<FileListResponse> {
|
||||
const params = new URLSearchParams({ path });
|
||||
if (showHidden) params.set('hidden', 'true');
|
||||
return request('GET', `/files/list?${params}`);
|
||||
}
|
||||
|
||||
export async function readFile(path: string): Promise<FileReadResponse> {
|
||||
return request('GET', `/files/read?path=${encodeURIComponent(path)}`);
|
||||
}
|
||||
|
||||
export async function getFileTree(path: string = '.', depth: number = 3): Promise<FileTreeResponse> {
|
||||
const params = new URLSearchParams({ path, depth: String(depth) });
|
||||
return request('GET', `/files/tree?${params}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user