feat: 实现文档集管理系统

新增功能:
   - 文档集创建:支持添加 .md/.txt/.v/.sv/.pdf 格式文件
   - 智能限制:单文件 10MB,总容量 50MB,最多 1000 个文件
   - 状态管理:实时显示索引状态(待索引/索引中/已索引)
   - 交互优化:支持文件预览、删除操作,带 loading 动画

   技术实现:
   - 新增 docsetDialog 组件处理文档集对话框
   - 新增 contextSettingsComponent 管理上下文设置
   - 扩展 contextHelper 支持文档集 CRUD 操作
   - 优化 messageRouter 处理文档集相关消息
This commit is contained in:
Roe-xin
2026-03-17 14:28:28 +08:00
parent 76c1af6e7e
commit 64cce80a70
6 changed files with 637 additions and 12 deletions

View File

@ -32,6 +32,8 @@ import {
handleAddContextFolder,
handleAddContextImage,
handleAddContextDocument,
handleAddContextDocumentSet,
handleGetDocumentSetList,
} from "./contextHelper";
import { openFile, openFileWithSelection, openFilePathTag } from "./fileHelper";
@ -356,6 +358,90 @@ export async function handleWebviewMessage(
await handleAddContextFolder(panel);
break;
case "addContextDocumentSet":
await handleAddContextDocumentSet(panel);
break;
case "getDocumentSetList":
await handleGetDocumentSetList(panel);
break;
case "saveDocumentSet":
const { saveDocumentSet } = await import("./contextHelper");
saveDocumentSet(message.documents || []);
break;
case "openContextSettings":
panel.webview.postMessage({
command: "openSettingsTab",
tab: "context"
});
break;
case "selectFilesForDocset":
const uris = await vscode.window.showOpenDialog({
canSelectMany: true,
canSelectFiles: true,
canSelectFolders: false,
openLabel: "选择文件",
filters: {
"支持的文件": ["md", "txt", "v", "sv", "pdf"],
},
});
if (uris && uris.length > 0) {
const fs = require("fs");
const path = require("path");
const selectedFiles: Array<{ path: string; relativePath: string; size: number }> = [];
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB
const MAX_TOTAL_SIZE = 50 * 1024 * 1024; // 50 MB
const MAX_FILES = 1000;
let totalSize = 0;
const errors: string[] = [];
for (const uri of uris) {
const filePath = uri.fsPath;
const ext = path.extname(filePath).toLowerCase();
if (![".md", ".txt", ".v", ".sv", ".pdf"].includes(ext)) {
errors.push(`文件 ${path.basename(filePath)} 格式不支持`);
continue;
}
try {
const stat = fs.statSync(filePath);
if (stat.size > MAX_FILE_SIZE) {
errors.push(`文件 ${path.basename(filePath)} 超过 10 MB`);
continue;
}
if (totalSize + stat.size > MAX_TOTAL_SIZE) {
errors.push("文档集总大小超过 50 MB");
break;
}
if (selectedFiles.length >= MAX_FILES) {
errors.push("文件数量超过 1000 个");
break;
}
selectedFiles.push({
path: filePath,
relativePath: vscode.workspace.asRelativePath(filePath),
size: stat.size,
});
totalSize += stat.size;
} catch (err) {
errors.push(`无法读取文件 ${path.basename(filePath)}`);
}
}
panel.webview.postMessage({
command: "filesSelectedForDocset",
files: selectedFiles,
errors: errors.length > 0 ? errors : undefined,
});
}
break;
case "addContextImage":
await handleAddContextImage(panel);
break;