完成了3点的修改:1、添加了文件系统监控,监控文件的动态变化,并及时ui显示。 2、添加了打开刷新,完善点1. 3、git上传优化,子集存在git上传时先删除子集git
This commit is contained in:
@@ -34,6 +34,13 @@ const ConfigView_1 = require("./views/ConfigView");
|
||||
const ProjectService_1 = require("./services/ProjectService");
|
||||
const GitService_1 = require("./services/GitService");
|
||||
const StorageService_1 = require("./services/StorageService");
|
||||
const debounce = (func, wait) => {
|
||||
let timeout;
|
||||
return (...args) => {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => func(...args), wait);
|
||||
};
|
||||
};
|
||||
class ConfigPanel {
|
||||
static createOrShow(extensionUri) {
|
||||
const column = vscode.window.activeTextEditor?.viewColumn || vscode.ViewColumn.One;
|
||||
@@ -61,15 +68,21 @@ class ConfigPanel {
|
||||
this.panel = panel;
|
||||
this.extensionUri = extensionUri;
|
||||
this.isWebviewDisposed = false;
|
||||
// 初始化服务
|
||||
this.projectService = new ProjectService_1.ProjectService();
|
||||
// 初始化视图
|
||||
this.projectView = new ProjectView_1.ProjectView(extensionUri);
|
||||
this.aircraftView = new AircraftView_1.AircraftView(extensionUri);
|
||||
this.containerView = new ContainerView_1.ContainerView(extensionUri);
|
||||
this.configView = new ConfigView_1.ConfigView(extensionUri);
|
||||
// 加载仓库配置
|
||||
void this.loadRepoConfigs();
|
||||
this.updateWebview();
|
||||
this.setupMessageListener();
|
||||
this.panel.onDidDispose(() => {
|
||||
if (this.fileWatcher) {
|
||||
this.fileWatcher.dispose();
|
||||
}
|
||||
this.isWebviewDisposed = true;
|
||||
ConfigPanel.currentPanel = undefined;
|
||||
});
|
||||
@@ -285,17 +298,32 @@ class ConfigPanel {
|
||||
}
|
||||
}
|
||||
async handleOpenProject(data) {
|
||||
// [新增] 在进入视图前,主动扫描磁盘同步数据
|
||||
const changed = await this.projectService.refreshProjectContent(data.projectId);
|
||||
if (changed) {
|
||||
await this.saveCurrentProjectData(); // 如果有变动,立即保存
|
||||
}
|
||||
this.currentView = 'aircrafts';
|
||||
this.currentProjectId = data.projectId;
|
||||
this.updateWebview();
|
||||
}
|
||||
async handleOpenAircraftConfig(data) {
|
||||
// [新增] 进入飞行器详情前,主动同步容器列表
|
||||
const changed = await this.projectService.refreshAircraftContent(data.aircraftId);
|
||||
if (changed) {
|
||||
await this.saveCurrentProjectData();
|
||||
}
|
||||
this.currentView = 'containers';
|
||||
this.currentProjectId = data.projectId;
|
||||
this.currentAircraftId = data.aircraftId;
|
||||
this.updateWebview();
|
||||
}
|
||||
async handleOpenContainerConfig(data) {
|
||||
// [新增] 进入容器详情前,主动同步配置和模块
|
||||
const changed = await this.projectService.refreshContainerContent(data.containerId);
|
||||
if (changed) {
|
||||
await this.saveCurrentProjectData();
|
||||
}
|
||||
this.currentView = 'configs';
|
||||
this.currentContainerId = data.containerId;
|
||||
this.updateWebview();
|
||||
@@ -1207,6 +1235,8 @@ class ConfigPanel {
|
||||
if (dirContents.length === 0) {
|
||||
throw new Error('目录为空,无法上传');
|
||||
}
|
||||
progress.report({ increment: 5, message: '清理嵌套仓库...' });
|
||||
await this.projectService.cleanNestedGitFolders(fullPath);
|
||||
let isGitRepo = false;
|
||||
if (fs.existsSync(path.join(fullPath, '.git'))) {
|
||||
isGitRepo = true;
|
||||
@@ -1470,6 +1500,8 @@ class ConfigPanel {
|
||||
if (projectId) {
|
||||
this.currentProjectId = projectId;
|
||||
this.currentView = 'aircrafts';
|
||||
// [新增] 项目加载成功后,启动文件监听
|
||||
this.setupFileWatcher(projectPath, projectId);
|
||||
vscode.window.showInformationMessage(`项目数据已从 ${projectPath} 加载`);
|
||||
this.updateWebview();
|
||||
return true;
|
||||
@@ -1481,6 +1513,87 @@ class ConfigPanel {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
setupFileWatcher(projectPath, projectId) {
|
||||
// 1. 如果已有监听器,先销毁
|
||||
if (this.fileWatcher) {
|
||||
this.fileWatcher.dispose();
|
||||
}
|
||||
// 2. 创建新的监听器:监听项目目录下的所有变化
|
||||
// Pattern: /path/to/project/**/*
|
||||
const pattern = new vscode.RelativePattern(projectPath, '**/*');
|
||||
this.fileWatcher = vscode.workspace.createFileSystemWatcher(pattern, false, true, false); // 忽略 onChange,只监听 Create/Delete
|
||||
// 3. 定义处理逻辑(使用防抖,避免连续创建文件导致多次刷新)
|
||||
const handleCreate = async (uri) => {
|
||||
if (this.isWebviewDisposed)
|
||||
return;
|
||||
const fsPath = uri.fsPath;
|
||||
const relativePath = path.relative(projectPath, fsPath);
|
||||
const parts = relativePath.split(path.sep); // 使用系统分隔符
|
||||
// 忽略 .git, .dcsp-data.json, 以及隐藏文件
|
||||
if (parts.some(p => p.startsWith('.') || p === 'dcsp-data.json'))
|
||||
return;
|
||||
let dataChanged = false;
|
||||
// 层级 1: 飞行器 (Folder)
|
||||
if (parts.length === 1) {
|
||||
// 检查是文件还是文件夹
|
||||
const stat = await vscode.workspace.fs.stat(uri);
|
||||
if ((stat.type & vscode.FileType.Directory) === vscode.FileType.Directory) {
|
||||
await this.projectService.importAircraftFromExistingFolder(projectId, parts[0]);
|
||||
dataChanged = true;
|
||||
}
|
||||
}
|
||||
// 层级 2: 容器 (Folder)
|
||||
else if (parts.length === 2) {
|
||||
const stat = await vscode.workspace.fs.stat(uri);
|
||||
if ((stat.type & vscode.FileType.Directory) === vscode.FileType.Directory) {
|
||||
const aircraft = this.projectService.getAircraftsByProject(projectId).find(a => a.name === parts[0]);
|
||||
if (aircraft) {
|
||||
await this.projectService.importContainerFromExistingFolder(aircraft.id, parts[1]);
|
||||
dataChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 层级 3: 配置 (File) 或 模块文件夹 (Folder)
|
||||
else if (parts.length === 3) {
|
||||
const [aircraftName, containerName, itemName] = parts;
|
||||
const aircraft = this.projectService.getAircraftsByProject(projectId).find(a => a.name === aircraftName);
|
||||
if (aircraft) {
|
||||
const container = this.projectService.getContainersByAircraft(aircraft.id).find(c => c.name === containerName);
|
||||
if (container) {
|
||||
const stat = await vscode.workspace.fs.stat(uri);
|
||||
if ((stat.type & vscode.FileType.File) === vscode.FileType.File) {
|
||||
// 是文件 -> 注册为 Config
|
||||
this.projectService.registerConfigFromDisk(itemName, itemName, container.id);
|
||||
dataChanged = true;
|
||||
}
|
||||
else if ((stat.type & vscode.FileType.Directory) === vscode.FileType.Directory) {
|
||||
// 是文件夹 -> 注册为 ModuleFolder
|
||||
this.projectService.registerModuleFolderFromDisk(itemName, container.id, aircraft.id, projectId, aircraftName, containerName);
|
||||
dataChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dataChanged) {
|
||||
await this.saveCurrentProjectData();
|
||||
this.updateWebview();
|
||||
}
|
||||
};
|
||||
const handleDelete = async (uri) => {
|
||||
if (this.isWebviewDisposed)
|
||||
return;
|
||||
const changed = this.projectService.removeEntityByPath(uri.fsPath, projectId);
|
||||
if (changed) {
|
||||
await this.saveCurrentProjectData();
|
||||
this.updateWebview();
|
||||
}
|
||||
};
|
||||
// 4. 绑定事件 (防抖建议设为 500ms 左右)
|
||||
const debouncedCreate = debounce(handleCreate, 500);
|
||||
const debouncedDelete = debounce(handleDelete, 500);
|
||||
this.fileWatcher.onDidCreate(uri => debouncedCreate(uri));
|
||||
this.fileWatcher.onDidDelete(uri => debouncedDelete(uri));
|
||||
}
|
||||
async saveCurrentProjectData() {
|
||||
if (!this.currentProjectId) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user