修复了保存的绝对路径问题
This commit is contained in:
@@ -55,16 +55,15 @@ class ConfigPanel {
|
|||||||
this.currentProjectId = '';
|
this.currentProjectId = '';
|
||||||
this.currentAircraftId = '';
|
this.currentAircraftId = '';
|
||||||
this.currentContainerId = '';
|
this.currentContainerId = '';
|
||||||
this.currentRepoId = '';
|
this.currentModuleFolderId = '';
|
||||||
// 数据存储
|
// 数据存储
|
||||||
this.projects = [];
|
this.projects = [];
|
||||||
this.aircrafts = [];
|
this.aircrafts = [];
|
||||||
this.containers = [];
|
this.containers = [];
|
||||||
this.configs = [];
|
this.configs = [];
|
||||||
this.gitRepos = []; // Git 仓库数据
|
this.moduleFolders = []; // 统一的模块文件夹数据
|
||||||
this.mergedFolders = [];
|
|
||||||
// Git 文件树
|
// Git 文件树
|
||||||
this.currentRepoFileTree = [];
|
this.currentModuleFolderFileTree = [];
|
||||||
// 项目存储路径映射
|
// 项目存储路径映射
|
||||||
this.projectPaths = new Map();
|
this.projectPaths = new Map();
|
||||||
// Webview 状态跟踪
|
// Webview 状态跟踪
|
||||||
@@ -129,7 +128,7 @@ class ConfigPanel {
|
|||||||
this.currentProjectId = '';
|
this.currentProjectId = '';
|
||||||
this.currentAircraftId = '';
|
this.currentAircraftId = '';
|
||||||
this.currentContainerId = '';
|
this.currentContainerId = '';
|
||||||
this.currentRepoId = '';
|
this.currentModuleFolderId = '';
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
break;
|
break;
|
||||||
case 'goBackToAircrafts':
|
case 'goBackToAircrafts':
|
||||||
@@ -194,20 +193,20 @@ class ConfigPanel {
|
|||||||
console.log('❌ 取消分支选择');
|
console.log('❌ 取消分支选择');
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
break;
|
break;
|
||||||
case 'loadGitRepo':
|
case 'loadModuleFolder':
|
||||||
await this.loadGitRepo(data.repoId);
|
await this.loadModuleFolder(data.folderId);
|
||||||
break;
|
break;
|
||||||
case 'syncGitRepo':
|
case 'syncGitModuleFolder':
|
||||||
await this.syncGitRepo(data.repoId);
|
await this.syncGitModuleFolder(data.folderId);
|
||||||
break;
|
break;
|
||||||
case 'deleteGitRepo':
|
case 'deleteModuleFolder':
|
||||||
await this.deleteGitRepo(data.repoId);
|
await this.deleteModuleFolder(data.folderId);
|
||||||
break;
|
break;
|
||||||
case 'importGitFile':
|
case 'importGitFile':
|
||||||
await this.importGitFile(data.filePath);
|
await this.importGitFile(data.filePath);
|
||||||
break;
|
break;
|
||||||
case 'openGitRepoInVSCode':
|
case 'openModuleFolderInVSCode':
|
||||||
await this.openTheModuleFolder('git', data.repoId);
|
await this.openTheModuleFolder(data.moduleType, data.folderId);
|
||||||
break;
|
break;
|
||||||
case 'openConfigFileInVSCode':
|
case 'openConfigFileInVSCode':
|
||||||
await this.openConfigFileInVSCode(data.configId);
|
await this.openConfigFileInVSCode(data.configId);
|
||||||
@@ -216,7 +215,7 @@ class ConfigPanel {
|
|||||||
await this.mergeConfigs(data.configIds, data.displayName, data.folderName);
|
await this.mergeConfigs(data.configIds, data.displayName, data.folderName);
|
||||||
break;
|
break;
|
||||||
case 'deleteMergedFolder':
|
case 'deleteMergedFolder':
|
||||||
await this.deleteMergedFolder(data.folderId);
|
await this.deleteModuleFolder(data.folderId);
|
||||||
break;
|
break;
|
||||||
case 'openMergedFolderInVSCode':
|
case 'openMergedFolderInVSCode':
|
||||||
await this.openTheModuleFolder('merged', data.folderId);
|
await this.openTheModuleFolder('merged', data.folderId);
|
||||||
@@ -316,9 +315,9 @@ class ConfigPanel {
|
|||||||
}
|
}
|
||||||
// === Git 仓库管理方法 ===
|
// === Git 仓库管理方法 ===
|
||||||
/**
|
/**
|
||||||
* 添加 Git 仓库到容器目录
|
* 添加 Git 模块文件夹到容器目录
|
||||||
*/
|
*/
|
||||||
async addGitRepo(url, name, branch) {
|
async addGitModuleFolder(url, name, branch) {
|
||||||
try {
|
try {
|
||||||
// 验证 URL
|
// 验证 URL
|
||||||
if (!url || !url.startsWith('http')) {
|
if (!url || !url.startsWith('http')) {
|
||||||
@@ -329,8 +328,8 @@ class ConfigPanel {
|
|||||||
vscode.window.showErrorMessage('请先选择容器');
|
vscode.window.showErrorMessage('请先选择容器');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const repoId = 'git-' + Date.now();
|
const folderId = 'git-' + Date.now();
|
||||||
// 构建本地路径 - 在容器目录下创建分支子目录
|
// 构建本地路径
|
||||||
const container = this.containers.find(c => c.id === this.currentContainerId);
|
const container = this.containers.find(c => c.id === this.currentContainerId);
|
||||||
if (!container) {
|
if (!container) {
|
||||||
vscode.window.showErrorMessage('未找到容器');
|
vscode.window.showErrorMessage('未找到容器');
|
||||||
@@ -346,33 +345,30 @@ class ConfigPanel {
|
|||||||
vscode.window.showErrorMessage('未找到项目路径');
|
vscode.window.showErrorMessage('未找到项目路径');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 为每个分支创建独立的子目录
|
// 构建相对路径(从项目路径开始)
|
||||||
const branchName = branch || 'main';
|
const relativePath = `/${aircraft.projectId}/${aircraft.name}/${container.name}/${name}`;
|
||||||
const branchSafeName = branchName.replace(/[^a-zA-Z0-9-_]/g, '-');
|
// 完整路径用于实际操作
|
||||||
const repoDirName = name;
|
const localPath = path.join(projectPath, aircraft.name, container.name, name);
|
||||||
// 路径:项目路径/飞行器名/容器名/仓库名-分支名/
|
console.log(`📁 Git模块文件夹将保存到: ${localPath}`);
|
||||||
const localPath = path.join(projectPath, aircraft.name, container.name, repoDirName);
|
console.log(`📁 相对路径: ${relativePath}`);
|
||||||
console.log(`📁 Git仓库将保存到: ${localPath}`);
|
// 检查是否已存在相同名称的模块文件夹
|
||||||
// 检查是否已存在相同 URL 和分支的仓库
|
const existingFolder = this.moduleFolders.find(folder => folder.name === name && folder.containerId === this.currentContainerId);
|
||||||
const existingRepo = this.gitRepos.find(repo => repo.url === url && repo.branch === branchName && repo.containerId === this.currentContainerId);
|
if (existingFolder) {
|
||||||
if (existingRepo) {
|
vscode.window.showWarningMessage('该名称的模块文件夹已存在');
|
||||||
vscode.window.showWarningMessage('该 Git 仓库和分支组合已存在');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const newRepo = {
|
const newFolder = {
|
||||||
id: repoId,
|
id: folderId,
|
||||||
name: `${name} (${branchName})`,
|
name: name,
|
||||||
url: url,
|
type: 'git',
|
||||||
localPath: localPath,
|
localPath: relativePath,
|
||||||
branch: branchName,
|
|
||||||
lastSync: new Date().toLocaleString(),
|
|
||||||
containerId: this.currentContainerId
|
containerId: this.currentContainerId
|
||||||
};
|
};
|
||||||
console.log(`📁 准备克隆仓库: ${name}, 分支: ${newRepo.branch}, 路径: ${localPath}`);
|
console.log(`📁 准备克隆仓库: ${name}, 分支: ${branch}, 路径: ${localPath}`);
|
||||||
// 显示进度
|
// 显示进度
|
||||||
await vscode.window.withProgress({
|
await vscode.window.withProgress({
|
||||||
location: vscode.ProgressLocation.Notification,
|
location: vscode.ProgressLocation.Notification,
|
||||||
title: `正在克隆仓库: ${name} (${newRepo.branch})`,
|
title: `正在克隆仓库: ${name}`,
|
||||||
cancellable: false
|
cancellable: false
|
||||||
}, async (progress) => {
|
}, async (progress) => {
|
||||||
progress.report({ increment: 0 });
|
progress.report({ increment: 0 });
|
||||||
@@ -403,7 +399,7 @@ class ConfigPanel {
|
|||||||
url: url,
|
url: url,
|
||||||
singleBranch: true,
|
singleBranch: true,
|
||||||
depth: 1,
|
depth: 1,
|
||||||
ref: branchName,
|
ref: branch || 'main',
|
||||||
onProgress: (event) => {
|
onProgress: (event) => {
|
||||||
if (event.total) {
|
if (event.total) {
|
||||||
const percent = (event.loaded / event.total) * 100;
|
const percent = (event.loaded / event.total) * 100;
|
||||||
@@ -412,17 +408,17 @@ class ConfigPanel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log('✅ Git克隆成功完成');
|
console.log('✅ Git克隆成功完成');
|
||||||
this.gitRepos.push(newRepo);
|
this.moduleFolders.push(newFolder);
|
||||||
await this.saveCurrentProjectData();
|
await this.saveCurrentProjectData();
|
||||||
console.log('✅ Git仓库数据已保存到项目文件');
|
console.log('✅ Git模块文件夹数据已保存到项目文件');
|
||||||
vscode.window.showInformationMessage(`Git 仓库克隆成功: ${name} (${newRepo.branch})`);
|
vscode.window.showInformationMessage(`Git 仓库克隆成功: ${name}`);
|
||||||
// 检查 Webview 状态后再加载文件树
|
// 检查 Webview 状态后再加载文件树
|
||||||
if (!this.isWebviewDisposed) {
|
if (!this.isWebviewDisposed) {
|
||||||
console.log('🌳 开始加载仓库文件树...');
|
console.log('🌳 开始加载模块文件夹文件树...');
|
||||||
// 自动加载仓库文件树
|
// 自动加载文件树
|
||||||
this.currentRepoId = repoId;
|
this.currentModuleFolderId = folderId;
|
||||||
await this.loadGitRepoFileTree(repoId);
|
await this.loadModuleFolderFileTree(folderId);
|
||||||
console.log('✅ 仓库文件树加载完成');
|
console.log('✅ 模块文件夹文件树加载完成');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log('⚠️ Webview 已被销毁,跳过文件树加载');
|
console.log('⚠️ Webview 已被销毁,跳过文件树加载');
|
||||||
@@ -435,30 +431,39 @@ class ConfigPanel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error('❌ 在addGitRepo外部捕获错误:', error);
|
console.error('❌ 在addGitModuleFolder外部捕获错误:', error);
|
||||||
vscode.window.showErrorMessage(`添加 Git 仓库失败: ${error}`);
|
vscode.window.showErrorMessage(`添加 Git 模块文件夹失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 加载 Git 仓库文件树
|
* 加载模块文件夹
|
||||||
*/
|
*/
|
||||||
async loadGitRepo(repoId) {
|
async loadModuleFolder(folderId) {
|
||||||
this.currentRepoId = repoId;
|
this.currentModuleFolderId = folderId;
|
||||||
await this.loadGitRepoFileTree(repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
|
if (folder && folder.type === 'git') {
|
||||||
|
await this.loadModuleFolderFileTree(folderId);
|
||||||
|
}
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 同步 Git 仓库
|
* 同步 Git 模块文件夹
|
||||||
*/
|
*/
|
||||||
async syncGitRepo(repoId) {
|
async syncGitModuleFolder(folderId) {
|
||||||
const repo = this.gitRepos.find(r => r.id === repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!repo) {
|
if (!folder || folder.type !== 'git') {
|
||||||
vscode.window.showErrorMessage('未找到指定的 Git 仓库');
|
vscode.window.showErrorMessage('未找到指定的 Git 模块文件夹');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 获取完整路径
|
||||||
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
|
if (!fullPath) {
|
||||||
|
vscode.window.showErrorMessage('无法获取模块文件夹的完整路径');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await vscode.window.withProgress({
|
await vscode.window.withProgress({
|
||||||
location: vscode.ProgressLocation.Notification,
|
location: vscode.ProgressLocation.Notification,
|
||||||
title: `正在同步仓库: ${repo.name}`,
|
title: `正在同步仓库: ${folder.name}`,
|
||||||
cancellable: false
|
cancellable: false
|
||||||
}, async (progress) => {
|
}, async (progress) => {
|
||||||
try {
|
try {
|
||||||
@@ -467,16 +472,13 @@ class ConfigPanel {
|
|||||||
await isomorphic_git_1.default.pull({
|
await isomorphic_git_1.default.pull({
|
||||||
fs: fs,
|
fs: fs,
|
||||||
http: node_1.default,
|
http: node_1.default,
|
||||||
dir: repo.localPath,
|
dir: fullPath,
|
||||||
author: { name: 'DCSP User', email: 'user@dcsp.local' },
|
author: { name: 'DCSP User', email: 'user@dcsp.local' },
|
||||||
fastForward: true
|
fastForward: true
|
||||||
});
|
});
|
||||||
// 更新最后同步时间
|
|
||||||
repo.lastSync = new Date().toLocaleString();
|
|
||||||
await this.saveCurrentProjectData();
|
|
||||||
// 重新加载文件树
|
// 重新加载文件树
|
||||||
await this.loadGitRepoFileTree(repoId);
|
await this.loadModuleFolderFileTree(folderId);
|
||||||
vscode.window.showInformationMessage(`Git 仓库同步成功: ${repo.name}`);
|
vscode.window.showInformationMessage(`Git 仓库同步成功: ${folder.name}`);
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
@@ -485,49 +487,52 @@ class ConfigPanel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 删除 Git 仓库
|
* 删除模块文件夹
|
||||||
*/
|
*/
|
||||||
async deleteGitRepo(repoId) {
|
async deleteModuleFolder(folderId) {
|
||||||
const repo = this.gitRepos.find(r => r.id === repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!repo)
|
if (!folder)
|
||||||
return;
|
return;
|
||||||
const confirm = await vscode.window.showWarningMessage(`确定要删除 Git 仓库 "${repo.name}" 吗?这将删除本地文件。`, { modal: true }, '确定删除', '取消');
|
const confirm = await vscode.window.showWarningMessage(`确定要删除模块文件夹 "${folder.name}" 吗?这将删除本地文件。`, { modal: true }, '确定删除', '取消');
|
||||||
if (confirm === '确定删除') {
|
if (confirm === '确定删除') {
|
||||||
try {
|
try {
|
||||||
// 删除整个仓库目录(因为是独立目录)
|
// 获取完整路径并删除文件夹
|
||||||
await fs.promises.rm(repo.localPath, { recursive: true, force: true });
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
// 从列表中移除
|
if (fullPath) {
|
||||||
this.gitRepos = this.gitRepos.filter(r => r.id !== repoId);
|
await fs.promises.rm(fullPath, { recursive: true, force: true });
|
||||||
await this.saveCurrentProjectData();
|
|
||||||
// 如果删除的是当前仓库,清空状态
|
|
||||||
if (this.currentRepoId === repoId) {
|
|
||||||
this.currentRepoId = '';
|
|
||||||
this.currentRepoFileTree = [];
|
|
||||||
}
|
}
|
||||||
vscode.window.showInformationMessage(`Git 仓库已删除: ${repo.name}`);
|
// 从列表中移除
|
||||||
|
this.moduleFolders = this.moduleFolders.filter(f => f.id !== folderId);
|
||||||
|
await this.saveCurrentProjectData();
|
||||||
|
// 如果删除的是当前文件夹,清空状态
|
||||||
|
if (this.currentModuleFolderId === folderId) {
|
||||||
|
this.currentModuleFolderId = '';
|
||||||
|
this.currentModuleFolderFileTree = [];
|
||||||
|
}
|
||||||
|
vscode.window.showInformationMessage(`模块文件夹已删除: ${folder.name}`);
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
vscode.window.showErrorMessage(`删除 Git 仓库失败: ${error}`);
|
vscode.window.showErrorMessage(`删除模块文件夹失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 加载 Git 仓库文件树
|
* 加载模块文件夹文件树
|
||||||
*/
|
*/
|
||||||
async loadGitRepoFileTree(repoId) {
|
async loadModuleFolderFileTree(folderId) {
|
||||||
// 检查 Webview 是否仍然有效
|
// 检查 Webview 是否仍然有效
|
||||||
if (this.isWebviewDisposed) {
|
if (this.isWebviewDisposed) {
|
||||||
console.log('⚠️ Webview 已被销毁,跳过文件树加载');
|
console.log('⚠️ Webview 已被销毁,跳过文件树加载');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const repo = this.gitRepos.find(r => r.id === repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!repo)
|
if (!folder)
|
||||||
return;
|
return;
|
||||||
// 通知前端开始加载
|
// 通知前端开始加载
|
||||||
try {
|
try {
|
||||||
this.panel.webview.postMessage({
|
this.panel.webview.postMessage({
|
||||||
type: 'gitRepoLoading',
|
type: 'moduleFolderLoading',
|
||||||
loading: true
|
loading: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -536,15 +541,15 @@ class ConfigPanel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const fileTree = await this.buildFileTree(repo.localPath);
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
this.currentRepoFileTree = fileTree;
|
if (fullPath) {
|
||||||
// 更新最后访问时间
|
const fileTree = await this.buildFileTree(fullPath);
|
||||||
repo.lastSync = new Date().toLocaleString();
|
this.currentModuleFolderFileTree = fileTree;
|
||||||
await this.saveCurrentProjectData();
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error('加载仓库文件树失败:', error);
|
console.error('加载模块文件夹文件树失败:', error);
|
||||||
this.currentRepoFileTree = [];
|
this.currentModuleFolderFileTree = [];
|
||||||
}
|
}
|
||||||
// 再次检查 Webview 状态
|
// 再次检查 Webview 状态
|
||||||
if (this.isWebviewDisposed) {
|
if (this.isWebviewDisposed) {
|
||||||
@@ -554,7 +559,7 @@ class ConfigPanel {
|
|||||||
// 通知前端加载完成
|
// 通知前端加载完成
|
||||||
try {
|
try {
|
||||||
this.panel.webview.postMessage({
|
this.panel.webview.postMessage({
|
||||||
type: 'gitRepoLoading',
|
type: 'moduleFolderLoading',
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
@@ -607,13 +612,13 @@ class ConfigPanel {
|
|||||||
* 导入 Git 文件到当前容器
|
* 导入 Git 文件到当前容器
|
||||||
*/
|
*/
|
||||||
async importGitFile(filePath) {
|
async importGitFile(filePath) {
|
||||||
if (!this.currentRepoId || !this.currentContainerId) {
|
if (!this.currentModuleFolderId || !this.currentContainerId) {
|
||||||
vscode.window.showErrorMessage('请先选择 Git 仓库和容器');
|
vscode.window.showErrorMessage('请先选择模块文件夹和容器');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const repo = this.gitRepos.find(r => r.id === this.currentRepoId);
|
const folder = this.moduleFolders.find(f => f.id === this.currentModuleFolderId);
|
||||||
if (!repo) {
|
if (!folder || folder.type !== 'git') {
|
||||||
vscode.window.showErrorMessage('未找到当前 Git 仓库');
|
vscode.window.showErrorMessage('未找到当前 Git 模块文件夹');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const container = this.containers.find(c => c.id === this.currentContainerId);
|
const container = this.containers.find(c => c.id === this.currentContainerId);
|
||||||
@@ -622,8 +627,13 @@ class ConfigPanel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const fullPath = path.join(repo.localPath, filePath);
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
const content = await fs.promises.readFile(fullPath, 'utf8');
|
if (!fullPath) {
|
||||||
|
vscode.window.showErrorMessage('无法获取模块文件夹路径');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const fileFullPath = path.join(fullPath, filePath);
|
||||||
|
const content = await fs.promises.readFile(fileFullPath, 'utf8');
|
||||||
const fileName = path.basename(filePath);
|
const fileName = path.basename(filePath);
|
||||||
// 创建新配置
|
// 创建新配置
|
||||||
const newId = 'cfg' + (this.configs.length + 1);
|
const newId = 'cfg' + (this.configs.length + 1);
|
||||||
@@ -685,20 +695,18 @@ class ConfigPanel {
|
|||||||
const currentProjectContainers = this.containers.filter(c => currentAircraftIds.includes(c.aircraftId));
|
const currentProjectContainers = this.containers.filter(c => currentAircraftIds.includes(c.aircraftId));
|
||||||
const currentContainerIds = currentProjectContainers.map(c => c.id);
|
const currentContainerIds = currentProjectContainers.map(c => c.id);
|
||||||
const currentProjectConfigs = this.configs.filter(cfg => currentContainerIds.includes(cfg.containerId));
|
const currentProjectConfigs = this.configs.filter(cfg => currentContainerIds.includes(cfg.containerId));
|
||||||
// 只保存与当前项目容器相关的 Git 仓库和合并文件夹
|
// 只保存与当前项目容器相关的模块文件夹
|
||||||
const currentProjectGitRepos = this.gitRepos.filter(repo => currentContainerIds.includes(repo.containerId));
|
const currentProjectModuleFolders = this.moduleFolders.filter(folder => currentContainerIds.includes(folder.containerId));
|
||||||
const currentProjectMergedFolders = this.mergedFolders.filter(folder => currentContainerIds.includes(folder.containerId));
|
|
||||||
const data = {
|
const data = {
|
||||||
projects: this.projects.filter(p => p.id === this.currentProjectId),
|
projects: this.projects.filter(p => p.id === this.currentProjectId),
|
||||||
aircrafts: currentProjectAircrafts,
|
aircrafts: currentProjectAircrafts,
|
||||||
containers: currentProjectContainers,
|
containers: currentProjectContainers,
|
||||||
configs: currentProjectConfigs,
|
configs: currentProjectConfigs,
|
||||||
gitRepos: currentProjectGitRepos,
|
moduleFolders: currentProjectModuleFolders // 保存模块文件夹数据
|
||||||
mergedFolders: currentProjectMergedFolders // 保存合并文件夹数据
|
|
||||||
};
|
};
|
||||||
const uint8Array = new TextEncoder().encode(JSON.stringify(data, null, 2));
|
const uint8Array = new TextEncoder().encode(JSON.stringify(data, null, 2));
|
||||||
await vscode.workspace.fs.writeFile(dataUri, uint8Array);
|
await vscode.workspace.fs.writeFile(dataUri, uint8Array);
|
||||||
console.log('✅ 当前项目数据已保存,包含', currentProjectGitRepos.length, '个 Git 仓库和', currentProjectMergedFolders.length, '个合并文件夹');
|
console.log('✅ 当前项目数据已保存,包含', currentProjectModuleFolders.length, '个模块文件夹');
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
vscode.window.showErrorMessage(`保存项目数据失败: ${error}`);
|
vscode.window.showErrorMessage(`保存项目数据失败: ${error}`);
|
||||||
@@ -727,8 +735,7 @@ class ConfigPanel {
|
|||||||
this.aircrafts = [];
|
this.aircrafts = [];
|
||||||
this.containers = [];
|
this.containers = [];
|
||||||
this.configs = [];
|
this.configs = [];
|
||||||
this.gitRepos = [];
|
this.moduleFolders = []; // 清空模块文件夹数据
|
||||||
this.mergedFolders = []; // 清空合并文件夹数据
|
|
||||||
// 验证数据格式并加载
|
// 验证数据格式并加载
|
||||||
if (data.projects && Array.isArray(data.projects)) {
|
if (data.projects && Array.isArray(data.projects)) {
|
||||||
this.projects = data.projects;
|
this.projects = data.projects;
|
||||||
@@ -742,11 +749,8 @@ class ConfigPanel {
|
|||||||
if (data.configs && Array.isArray(data.configs)) {
|
if (data.configs && Array.isArray(data.configs)) {
|
||||||
this.configs = data.configs;
|
this.configs = data.configs;
|
||||||
}
|
}
|
||||||
if (data.gitRepos && Array.isArray(data.gitRepos)) {
|
if (data.moduleFolders && Array.isArray(data.moduleFolders)) {
|
||||||
this.gitRepos = data.gitRepos;
|
this.moduleFolders = data.moduleFolders; // 加载模块文件夹数据
|
||||||
}
|
|
||||||
if (data.mergedFolders && Array.isArray(data.mergedFolders)) {
|
|
||||||
this.mergedFolders = data.mergedFolders; // 加载合并文件夹数据
|
|
||||||
}
|
}
|
||||||
// 设置当前项目为第一个项目(如果有的话)
|
// 设置当前项目为第一个项目(如果有的话)
|
||||||
if (this.projects.length > 0) {
|
if (this.projects.length > 0) {
|
||||||
@@ -754,7 +758,7 @@ class ConfigPanel {
|
|||||||
this.projectPaths.set(this.currentProjectId, projectPath);
|
this.projectPaths.set(this.currentProjectId, projectPath);
|
||||||
this.currentView = 'aircrafts';
|
this.currentView = 'aircrafts';
|
||||||
}
|
}
|
||||||
vscode.window.showInformationMessage(`项目数据已从 ${projectPath} 加载,包含 ${this.gitRepos.length} 个 Git 仓库和 ${this.mergedFolders.length} 个合并文件夹`);
|
vscode.window.showInformationMessage(`项目数据已从 ${projectPath} 加载,包含 ${this.moduleFolders.length} 个模块文件夹`);
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -905,8 +909,8 @@ class ConfigPanel {
|
|||||||
// 删除相关的配置
|
// 删除相关的配置
|
||||||
const containerIds = this.containers.filter(c => aircraftIds.includes(c.aircraftId)).map(c => c.id);
|
const containerIds = this.containers.filter(c => aircraftIds.includes(c.aircraftId)).map(c => c.id);
|
||||||
this.configs = this.configs.filter(cfg => !containerIds.includes(cfg.containerId));
|
this.configs = this.configs.filter(cfg => !containerIds.includes(cfg.containerId));
|
||||||
// 删除相关的 Git 仓库
|
// 删除相关的模块文件夹
|
||||||
this.gitRepos = this.gitRepos.filter(repo => !containerIds.includes(repo.containerId));
|
this.moduleFolders = this.moduleFolders.filter(folder => !containerIds.includes(folder.containerId));
|
||||||
// 删除项目路径映射
|
// 删除项目路径映射
|
||||||
this.projectPaths.delete(projectId);
|
this.projectPaths.delete(projectId);
|
||||||
vscode.window.showInformationMessage(`删除项目: ${project.name}`);
|
vscode.window.showInformationMessage(`删除项目: ${project.name}`);
|
||||||
@@ -953,8 +957,8 @@ class ConfigPanel {
|
|||||||
// 删除相关的配置
|
// 删除相关的配置
|
||||||
const containerIds = this.containers.filter(c => c.aircraftId === aircraftId).map(c => c.id);
|
const containerIds = this.containers.filter(c => c.aircraftId === aircraftId).map(c => c.id);
|
||||||
this.configs = this.configs.filter(cfg => !containerIds.includes(cfg.containerId));
|
this.configs = this.configs.filter(cfg => !containerIds.includes(cfg.containerId));
|
||||||
// 删除相关的 Git 仓库
|
// 删除相关的模块文件夹
|
||||||
this.gitRepos = this.gitRepos.filter(repo => !containerIds.includes(repo.containerId));
|
this.moduleFolders = this.moduleFolders.filter(folder => !containerIds.includes(folder.containerId));
|
||||||
vscode.window.showInformationMessage(`删除飞行器: ${aircraft.name}`);
|
vscode.window.showInformationMessage(`删除飞行器: ${aircraft.name}`);
|
||||||
await this.saveCurrentProjectData();
|
await this.saveCurrentProjectData();
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
@@ -1015,8 +1019,8 @@ class ConfigPanel {
|
|||||||
this.containers = this.containers.filter(c => c.id !== containerId);
|
this.containers = this.containers.filter(c => c.id !== containerId);
|
||||||
// 删除相关的配置
|
// 删除相关的配置
|
||||||
this.configs = this.configs.filter(cfg => cfg.containerId !== containerId);
|
this.configs = this.configs.filter(cfg => cfg.containerId !== containerId);
|
||||||
// 删除相关的 Git 仓库
|
// 删除相关的模块文件夹
|
||||||
this.gitRepos = this.gitRepos.filter(repo => repo.containerId !== containerId);
|
this.moduleFolders = this.moduleFolders.filter(folder => folder.containerId !== containerId);
|
||||||
vscode.window.showInformationMessage(`删除容器: ${container.name}`);
|
vscode.window.showInformationMessage(`删除容器: ${container.name}`);
|
||||||
await this.saveCurrentProjectData();
|
await this.saveCurrentProjectData();
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
@@ -1204,7 +1208,7 @@ class ConfigPanel {
|
|||||||
message: `克隆分支: ${branch} (${i + 1}/${branches.length})`
|
message: `克隆分支: ${branch} (${i + 1}/${branches.length})`
|
||||||
});
|
});
|
||||||
console.log(`📥 克隆分支: ${branch}`);
|
console.log(`📥 克隆分支: ${branch}`);
|
||||||
await this.addGitRepo(url, this.generateRepoName(url, branch), branch);
|
await this.addGitModuleFolder(url, this.generateModuleFolderName(url, branch), branch);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
vscode.window.showInformationMessage(`成功克隆 ${branches.length} 个分支`);
|
vscode.window.showInformationMessage(`成功克隆 ${branches.length} 个分支`);
|
||||||
@@ -1214,7 +1218,7 @@ class ConfigPanel {
|
|||||||
vscode.window.showErrorMessage(`克隆分支失败: ${error}`);
|
vscode.window.showErrorMessage(`克隆分支失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
generateRepoName(url, branch) {
|
generateModuleFolderName(url, branch) {
|
||||||
const repoName = url.split('/').pop()?.replace('.git', '') || 'unknown-repo';
|
const repoName = url.split('/').pop()?.replace('.git', '') || 'unknown-repo';
|
||||||
const branchSafeName = branch.replace(/[^a-zA-Z0-9-_]/g, '-');
|
const branchSafeName = branch.replace(/[^a-zA-Z0-9-_]/g, '-');
|
||||||
return `${repoName}-${branchSafeName}`;
|
return `${repoName}-${branchSafeName}`;
|
||||||
@@ -1257,18 +1261,16 @@ class ConfigPanel {
|
|||||||
case 'configs':
|
case 'configs':
|
||||||
const currentContainer = this.containers.find(c => c.id === this.currentContainerId);
|
const currentContainer = this.containers.find(c => c.id === this.currentContainerId);
|
||||||
const containerConfigs = this.configs.filter(cfg => cfg.containerId === this.currentContainerId);
|
const containerConfigs = this.configs.filter(cfg => cfg.containerId === this.currentContainerId);
|
||||||
const currentRepo = this.gitRepos.find(r => r.id === this.currentRepoId);
|
const currentModuleFolder = this.moduleFolders.find(f => f.id === this.currentModuleFolderId);
|
||||||
// 获取当前容器的 Git 仓库和合并文件夹
|
// 获取当前容器的模块文件夹
|
||||||
const containerGitRepos = this.gitRepos.filter(repo => repo.containerId === this.currentContainerId);
|
const containerModuleFolders = this.moduleFolders.filter(folder => folder.containerId === this.currentContainerId);
|
||||||
const containerMergedFolders = this.mergedFolders.filter(folder => folder.containerId === this.currentContainerId);
|
|
||||||
return this.configView.render({
|
return this.configView.render({
|
||||||
container: currentContainer,
|
container: currentContainer,
|
||||||
configs: containerConfigs,
|
configs: containerConfigs,
|
||||||
gitRepos: containerGitRepos,
|
moduleFolders: containerModuleFolders,
|
||||||
currentGitRepo: currentRepo,
|
currentModuleFolder: currentModuleFolder,
|
||||||
gitFileTree: this.currentRepoFileTree,
|
moduleFolderFileTree: this.currentModuleFolderFileTree,
|
||||||
gitLoading: false,
|
moduleFolderLoading: false
|
||||||
mergedFolders: containerMergedFolders // 传递合并文件夹数据
|
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
return this.projectView.render({
|
return this.projectView.render({
|
||||||
@@ -1277,26 +1279,27 @@ class ConfigPanel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async openGitRepoInVSCode(repoId) {
|
async openGitRepoInVSCode(folderId) {
|
||||||
const repo = this.gitRepos.find(r => r.id === repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!repo) {
|
if (!folder) {
|
||||||
vscode.window.showErrorMessage('未找到指定的 Git 仓库');
|
vscode.window.showErrorMessage('未找到指定的模块文件夹');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 检查仓库目录是否存在
|
// 检查文件夹是否存在
|
||||||
if (!fs.existsSync(repo.localPath)) {
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
vscode.window.showErrorMessage('Git 仓库目录不存在,请重新克隆');
|
if (!fullPath || !fs.existsSync(fullPath)) {
|
||||||
|
vscode.window.showErrorMessage('模块文件夹目录不存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 使用 VSCode 的文件选择器让用户选择要打开的文件
|
// 使用 VSCode 的文件选择器让用户选择要打开的文件
|
||||||
const fileUri = await vscode.window.showOpenDialog({
|
const fileUri = await vscode.window.showOpenDialog({
|
||||||
defaultUri: vscode.Uri.file(repo.localPath),
|
defaultUri: vscode.Uri.file(fullPath),
|
||||||
canSelectFiles: true,
|
canSelectFiles: true,
|
||||||
canSelectFolders: false,
|
canSelectFolders: false,
|
||||||
canSelectMany: false,
|
canSelectMany: false,
|
||||||
openLabel: '选择要打开的文件',
|
openLabel: '选择要打开的文件',
|
||||||
title: `在 ${repo.name} 中选择文件`
|
title: `在 ${folder.name} 中选择文件`
|
||||||
});
|
});
|
||||||
if (fileUri && fileUri.length > 0) {
|
if (fileUri && fileUri.length > 0) {
|
||||||
// 打开选中的文件
|
// 打开选中的文件
|
||||||
@@ -1306,7 +1309,7 @@ class ConfigPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
vscode.window.showErrorMessage(`打开 Git 仓库文件失败: ${error}`);
|
vscode.window.showErrorMessage(`打开模块文件夹文件失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async openConfigFileInVSCode(configId) {
|
async openConfigFileInVSCode(configId) {
|
||||||
@@ -1401,19 +1404,18 @@ class ConfigPanel {
|
|||||||
console.log(`✅ 已创建配置文件: ${config.fileName}`);
|
console.log(`✅ 已创建配置文件: ${config.fileName}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 构建相对路径
|
||||||
|
const relativePath = `/${aircraft.projectId}/${aircraft.name}/${container.name}/${folderName}`;
|
||||||
// 创建合并文件夹记录
|
// 创建合并文件夹记录
|
||||||
const newFolder = {
|
const newFolder = {
|
||||||
id: 'merged-' + Date.now(),
|
id: 'merged-' + Date.now(),
|
||||||
displayName: displayName,
|
name: displayName,
|
||||||
folderName: folderName,
|
type: 'merged',
|
||||||
path: mergeFolderPath,
|
localPath: relativePath,
|
||||||
fileCount: copiedFiles.length,
|
containerId: this.currentContainerId
|
||||||
containerId: this.currentContainerId,
|
|
||||||
originalConfigIds: configIds,
|
|
||||||
createdAt: new Date().toLocaleString()
|
|
||||||
};
|
};
|
||||||
// 添加到合并文件夹列表
|
// 添加到模块文件夹列表
|
||||||
this.mergedFolders.push(newFolder);
|
this.moduleFolders.push(newFolder);
|
||||||
// 删除原始配置文件
|
// 删除原始配置文件
|
||||||
for (const configId of configIds) {
|
for (const configId of configIds) {
|
||||||
await this.deleteConfigInternal(configId);
|
await this.deleteConfigInternal(configId);
|
||||||
@@ -1421,7 +1423,7 @@ class ConfigPanel {
|
|||||||
// 保存数据
|
// 保存数据
|
||||||
await this.saveCurrentProjectData();
|
await this.saveCurrentProjectData();
|
||||||
vscode.window.showInformationMessage(`成功合并 ${selectedConfigs.length} 个配置文件到文件夹: ${folderName}`);
|
vscode.window.showInformationMessage(`成功合并 ${selectedConfigs.length} 个配置文件到文件夹: ${folderName}`);
|
||||||
// 更新UI(不自动打开文件夹)
|
// 更新UI
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
@@ -1461,50 +1463,28 @@ class ConfigPanel {
|
|||||||
console.error(`删除配置文件失败: ${error}`);
|
console.error(`删除配置文件失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 删除合并文件夹
|
|
||||||
*/
|
|
||||||
async deleteMergedFolder(folderId) {
|
|
||||||
const folder = this.mergedFolders.find(f => f.id === folderId);
|
|
||||||
if (!folder)
|
|
||||||
return;
|
|
||||||
const confirm = await vscode.window.showWarningMessage(`确定要删除合并文件夹 "${folder.displayName}" 吗?这将删除文件夹及其所有内容。`, { modal: true }, '确定删除', '取消');
|
|
||||||
if (confirm === '确定删除') {
|
|
||||||
try {
|
|
||||||
// 删除文件夹及其所有内容
|
|
||||||
await fs.promises.rm(folder.path, { recursive: true, force: true });
|
|
||||||
// 从列表中移除
|
|
||||||
this.mergedFolders = this.mergedFolders.filter(f => f.id !== folderId);
|
|
||||||
await this.saveCurrentProjectData();
|
|
||||||
vscode.window.showInformationMessage(`合并文件夹已删除: ${folder.displayName}`);
|
|
||||||
this.updateWebview();
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
vscode.window.showErrorMessage(`删除合并文件夹失败: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 在 VSCode 中打开合并文件夹
|
* 在 VSCode 中打开合并文件夹
|
||||||
*/
|
*/
|
||||||
async openMergedFolderInVSCode(folderId) {
|
async openMergedFolderInVSCode(folderId) {
|
||||||
const folder = this.mergedFolders.find(f => f.id === folderId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
vscode.window.showErrorMessage('未找到指定的合并文件夹');
|
vscode.window.showErrorMessage('未找到指定的模块文件夹');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 检查文件夹是否存在
|
// 检查文件夹是否存在
|
||||||
if (!fs.existsSync(folder.path)) {
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
vscode.window.showErrorMessage('合并文件夹不存在');
|
if (!fullPath || !fs.existsSync(fullPath)) {
|
||||||
|
vscode.window.showErrorMessage('模块文件夹不存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 使用 VSCode 打开文件夹
|
// 使用 VSCode 打开文件夹
|
||||||
const folderUri = vscode.Uri.file(folder.path);
|
const folderUri = vscode.Uri.file(fullPath);
|
||||||
vscode.commands.executeCommand('vscode.openFolder', folderUri, { forceNewWindow: false });
|
vscode.commands.executeCommand('vscode.openFolder', folderUri, { forceNewWindow: false });
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
vscode.window.showErrorMessage(`打开合并文件夹失败: ${error}`);
|
vscode.window.showErrorMessage(`打开模块文件夹失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -1513,44 +1493,26 @@ class ConfigPanel {
|
|||||||
* @param id 模块 ID
|
* @param id 模块 ID
|
||||||
*/
|
*/
|
||||||
async openTheModuleFolder(type, id) {
|
async openTheModuleFolder(type, id) {
|
||||||
let folderPath;
|
const folder = this.moduleFolders.find(f => f.id === id);
|
||||||
let folderName;
|
|
||||||
if (type === 'git') {
|
|
||||||
const repo = this.gitRepos.find(r => r.id === id);
|
|
||||||
if (!repo) {
|
|
||||||
vscode.window.showErrorMessage('未找到指定的 Git 仓库');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
folderPath = repo.localPath;
|
|
||||||
folderName = repo.name;
|
|
||||||
}
|
|
||||||
else if (type === 'merged') {
|
|
||||||
const folder = this.mergedFolders.find(f => f.id === id);
|
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
vscode.window.showErrorMessage('未找到指定的合并文件夹');
|
vscode.window.showErrorMessage('未找到指定的模块文件夹');
|
||||||
return;
|
|
||||||
}
|
|
||||||
folderPath = folder.path;
|
|
||||||
folderName = folder.displayName;
|
|
||||||
}
|
|
||||||
if (!folderPath) {
|
|
||||||
vscode.window.showErrorMessage('未找到文件夹路径');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 检查文件夹是否存在
|
// 检查文件夹是否存在
|
||||||
if (!fs.existsSync(folderPath)) {
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
vscode.window.showErrorMessage(`${type === 'git' ? 'Git 仓库' : '合并文件夹'}目录不存在`);
|
if (!fullPath || !fs.existsSync(fullPath)) {
|
||||||
|
vscode.window.showErrorMessage('模块文件夹目录不存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 使用 VSCode 的文件选择器让用户选择要打开的文件
|
// 使用 VSCode 的文件选择器让用户选择要打开的文件
|
||||||
const fileUri = await vscode.window.showOpenDialog({
|
const fileUri = await vscode.window.showOpenDialog({
|
||||||
defaultUri: vscode.Uri.file(folderPath),
|
defaultUri: vscode.Uri.file(fullPath),
|
||||||
canSelectFiles: true,
|
canSelectFiles: true,
|
||||||
canSelectFolders: false,
|
canSelectFolders: false,
|
||||||
canSelectMany: false,
|
canSelectMany: false,
|
||||||
openLabel: '选择要打开的文件',
|
openLabel: '选择要打开的文件',
|
||||||
title: `在 ${folderName} 中选择文件`
|
title: `在 ${folder.name} 中选择文件`
|
||||||
});
|
});
|
||||||
if (fileUri && fileUri.length > 0) {
|
if (fileUri && fileUri.length > 0) {
|
||||||
// 打开选中的文件
|
// 打开选中的文件
|
||||||
@@ -1560,9 +1522,29 @@ class ConfigPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
vscode.window.showErrorMessage(`打开${type === 'git' ? 'Git 仓库' : '合并文件夹'}文件失败: ${error}`);
|
vscode.window.showErrorMessage(`打开模块文件夹文件失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取模块文件夹的完整路径
|
||||||
|
*/
|
||||||
|
getModuleFolderFullPath(folder) {
|
||||||
|
const container = this.containers.find(c => c.id === folder.containerId);
|
||||||
|
if (!container)
|
||||||
|
return null;
|
||||||
|
const aircraft = this.aircrafts.find(a => a.id === container.aircraftId);
|
||||||
|
if (!aircraft)
|
||||||
|
return null;
|
||||||
|
const projectPath = this.projectPaths.get(aircraft.projectId);
|
||||||
|
if (!projectPath)
|
||||||
|
return null;
|
||||||
|
// 从相对路径解析出文件夹名称
|
||||||
|
const pathParts = folder.localPath.split('/').filter(part => part);
|
||||||
|
if (pathParts.length < 4)
|
||||||
|
return null;
|
||||||
|
const folderName = pathParts[pathParts.length - 1];
|
||||||
|
return path.join(projectPath, aircraft.name, container.name, folderName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.ConfigPanel = ConfigPanel;
|
exports.ConfigPanel = ConfigPanel;
|
||||||
//# sourceMappingURL=ConfigPanel.js.map
|
//# sourceMappingURL=ConfigPanel.js.map
|
||||||
File diff suppressed because one or more lines are too long
4
out/panels/types/DataTypes.js
Normal file
4
out/panels/types/DataTypes.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
"use strict";
|
||||||
|
// src/types/DataTypes.ts
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
//# sourceMappingURL=DataTypes.js.map
|
||||||
1
out/panels/types/DataTypes.js.map
Normal file
1
out/panels/types/DataTypes.js.map
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"DataTypes.js","sourceRoot":"","sources":["../../../src/panels/types/DataTypes.ts"],"names":[],"mappings":";AAAA,yBAAyB"}
|
||||||
@@ -6,14 +6,13 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
render(data) {
|
render(data) {
|
||||||
const container = data?.container;
|
const container = data?.container;
|
||||||
const configs = data?.configs || [];
|
const configs = data?.configs || [];
|
||||||
const gitRepos = data?.gitRepos || [];
|
const moduleFolders = data?.moduleFolders || [];
|
||||||
const currentGitRepo = data?.currentGitRepo;
|
const currentModuleFolder = data?.currentModuleFolder;
|
||||||
const gitFileTree = data?.gitFileTree || [];
|
const moduleFolderFileTree = data?.moduleFolderFileTree || [];
|
||||||
const gitLoading = data?.gitLoading || false;
|
const moduleFolderLoading = data?.moduleFolderLoading || false;
|
||||||
const gitBranches = data?.gitBranches || [];
|
const gitBranches = data?.gitBranches || [];
|
||||||
const gitRepoUrl = data?.gitRepoUrl || '';
|
const gitRepoUrl = data?.gitRepoUrl || '';
|
||||||
const mergedFolders = data?.mergedFolders || [];
|
// 生成配置列表的 HTML - 包含配置文件和模块文件夹
|
||||||
// 生成配置列表的 HTML - 包含配置文件和 Git 仓库
|
|
||||||
const configsHtml = configs.map((config) => `
|
const configsHtml = configs.map((config) => `
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@@ -28,39 +27,22 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`).join('');
|
`).join('');
|
||||||
// 生成合并文件夹的 HTML - 显示在配置列表中
|
// 生成模块文件夹的 HTML - 统一显示 Git 和合并文件夹
|
||||||
const mergedFoldersHtml = mergedFolders.map((folder) => `
|
const moduleFoldersHtml = moduleFolders.map((folder) => {
|
||||||
<tr>
|
const icon = folder.type === 'git' ? '📁' : '📁';
|
||||||
<td>
|
|
||||||
<span class="editable">📁 ${folder.displayName}</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="clickable" onclick="openTheModuleFolder('${folder.id}', 'merged')">${folder.folderName}</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn-delete" onclick="deleteMergedFolder('${folder.id}')">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
`).join('');
|
|
||||||
// 生成 Git 仓库列表的 HTML - 修改显示方式,Git 仓库不可勾选
|
|
||||||
const gitReposHtml = gitRepos.map(repo => {
|
|
||||||
// 提取仓库名称(从URL中获取或使用name)
|
|
||||||
const repoName = repo.name.split(' (')[0]; // 移除分支名部分
|
|
||||||
// 提取分支名
|
|
||||||
const branchMatch = repo.name.match(/\(([^)]+)\)/);
|
|
||||||
const branchName = branchMatch ? branchMatch[1] : repo.branch;
|
|
||||||
return `
|
return `
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span class="editable">📁 ${repoName}</span>
|
<span class="editable">${icon} ${folder.name}</span>
|
||||||
<div style="font-size: 12px; color: var(--vscode-descriptionForeground); margin-top: 4px;">
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="clickable" onclick="openTheModuleFolder('${repo.id}', 'git')">${branchName}</span>
|
<span class="clickable" onclick="openTheModuleFolder('${folder.id}', '${folder.type}')">${folder.localPath.split('/').pop()}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn-delete" onclick="deleteGitRepo('${repo.id}')">删除</button>
|
${folder.type === 'git' ? `
|
||||||
|
<button class="btn-sync" onclick="syncModuleFolder('${folder.id}')" style="margin-right: 5px;">同步</button>
|
||||||
|
` : ''}
|
||||||
|
<button class="btn-delete" onclick="deleteModuleFolder('${folder.id}')">删除</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
@@ -110,6 +92,19 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-sync {
|
||||||
|
background: var(--vscode-button-background);
|
||||||
|
color: var(--vscode-button-foreground);
|
||||||
|
padding: 4px 8px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sync:hover {
|
||||||
|
background: var(--vscode-button-hoverBackground);
|
||||||
|
}
|
||||||
|
|
||||||
/* 树状分支样式 */
|
/* 树状分支样式 */
|
||||||
.branch-tree {
|
.branch-tree {
|
||||||
font-family: 'Courier New', monospace;
|
font-family: 'Courier New', monospace;
|
||||||
@@ -251,21 +246,20 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="30%">配置</th>
|
<th width="30%">配置</th>
|
||||||
<th width="40%">文件</th>
|
<th width="40%">文件/文件夹</th>
|
||||||
<th width="30%">操作</th>
|
<th width="30%">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
${configsHtml}
|
${configsHtml}
|
||||||
${mergedFoldersHtml}
|
${moduleFoldersHtml}
|
||||||
${gitReposHtml}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Git 仓库管理部分 -->
|
<!-- 模块文件夹管理部分 -->
|
||||||
<div class="config-section">
|
<div class="config-section">
|
||||||
<h3 class="section-title">📚 Git 仓库管理</h3>
|
<h3 class="section-title">📚 模块云仓库</h3>
|
||||||
|
|
||||||
<!-- URL 输入区域 -->
|
<!-- URL 输入区域 -->
|
||||||
<div class="url-input-section">
|
<div class="url-input-section">
|
||||||
@@ -319,8 +313,7 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 统一功能:打开模块文件夹
|
||||||
// 统一功能:打开模块文件夹(合并 Git 仓库和合并文件夹功能)
|
|
||||||
function openTheModuleFolder(id, type) {
|
function openTheModuleFolder(id, type) {
|
||||||
console.log('📂 打开模块文件夹:', { id, type });
|
console.log('📂 打开模块文件夹:', { id, type });
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
@@ -364,46 +357,34 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除合并文件夹功能
|
// 删除模块文件夹功能
|
||||||
function deleteMergedFolder(folderId) {
|
function deleteModuleFolder(folderId) {
|
||||||
console.log('🗑️ 尝试删除合并文件夹:', folderId);
|
console.log('🗑️ 尝试删除模块文件夹:', folderId);
|
||||||
|
|
||||||
showConfirmDialog(
|
showConfirmDialog(
|
||||||
'确认删除合并文件夹',
|
'确认删除模块文件夹',
|
||||||
'确定删除这个合并文件夹吗?这将删除文件夹及其所有内容。',
|
'确定删除这个模块文件夹吗?这将删除文件夹及其所有内容。',
|
||||||
function() {
|
function() {
|
||||||
console.log('✅ 用户确认删除合并文件夹:', folderId);
|
console.log('✅ 用户确认删除模块文件夹:', folderId);
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
type: 'deleteMergedFolder',
|
type: 'deleteModuleFolder',
|
||||||
folderId: folderId
|
folderId: folderId
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
// 用户取消删除
|
// 用户取消删除
|
||||||
console.log('❌ 用户取消删除合并文件夹');
|
console.log('❌ 用户取消删除模块文件夹');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Git 仓库删除功能
|
// 同步 Git 模块文件夹
|
||||||
function deleteGitRepo(repoId) {
|
function syncModuleFolder(folderId) {
|
||||||
console.log('🗑️ 尝试删除 Git 仓库:', repoId);
|
console.log('🔄 同步模块文件夹:', folderId);
|
||||||
|
|
||||||
showConfirmDialog(
|
|
||||||
'确认删除 Git 仓库',
|
|
||||||
'确定删除这个 Git 仓库吗?这将删除本地克隆的代码文件夹。',
|
|
||||||
function() {
|
|
||||||
console.log('✅ 用户确认删除 Git 仓库:', repoId);
|
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
type: 'deleteGitRepo',
|
type: 'syncGitModuleFolder',
|
||||||
repoId: repoId
|
folderId: folderId
|
||||||
});
|
});
|
||||||
},
|
|
||||||
function() {
|
|
||||||
// 用户取消删除
|
|
||||||
console.log('❌ 用户取消删除 Git 仓库');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function goBackToContainers() {
|
function goBackToContainers() {
|
||||||
@@ -480,14 +461,6 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncGitRepo(repoId) {
|
|
||||||
console.log('🔄 同步仓库:', repoId);
|
|
||||||
vscode.postMessage({
|
|
||||||
type: 'syncGitRepo',
|
|
||||||
repoId: repoId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置文件合并功能
|
// 配置文件合并功能
|
||||||
function toggleConfigSelection(configId) {
|
function toggleConfigSelection(configId) {
|
||||||
const checkbox = document.querySelector('.config-checkbox[data-id="' + configId + '"]');
|
const checkbox = document.querySelector('.config-checkbox[data-id="' + configId + '"]');
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
4
out/types/DataTypes.js
Normal file
4
out/types/DataTypes.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
"use strict";
|
||||||
|
// src/types/DataTypes.ts
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
//# sourceMappingURL=DataTypes.js.map
|
||||||
1
out/types/DataTypes.js.map
Normal file
1
out/types/DataTypes.js.map
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"DataTypes.js","sourceRoot":"","sources":["../../src/types/DataTypes.ts"],"names":[],"mappings":";AAAA,yBAAyB"}
|
||||||
@@ -34,15 +34,13 @@ interface Config {
|
|||||||
containerId: string;
|
containerId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Git 仓库接口
|
// 统一的模块文件夹接口,合并 gitRepos 和 mergedFolders
|
||||||
interface GitRepo {
|
interface ModuleFolder {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
type: 'git' | 'merged'; // 类型标识
|
||||||
localPath: string;
|
localPath: string; // 相对路径,如 "/项目1/飞行器1/容器1/test-code"
|
||||||
branch: string;
|
containerId: string;
|
||||||
lastSync: string;
|
|
||||||
containerId: string; // 关联到特定容器
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GitFileTree {
|
interface GitFileTree {
|
||||||
@@ -59,25 +57,13 @@ interface GitBranch {
|
|||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MergedFolder {
|
// 修改 ProjectData 接口,使用统一的 moduleFolders
|
||||||
id: string;
|
|
||||||
displayName: string; // 配置栏显示的名称
|
|
||||||
folderName: string; // 实际文件夹名称
|
|
||||||
path: string;
|
|
||||||
fileCount: number;
|
|
||||||
containerId: string;
|
|
||||||
originalConfigIds: string[];
|
|
||||||
createdAt: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改 ProjectData 接口,添加 mergedFolders
|
|
||||||
interface ProjectData {
|
interface ProjectData {
|
||||||
projects: Project[];
|
projects: Project[];
|
||||||
aircrafts: Aircraft[];
|
aircrafts: Aircraft[];
|
||||||
containers: Container[];
|
containers: Container[];
|
||||||
configs: Config[];
|
configs: Config[];
|
||||||
gitRepos: GitRepo[];
|
moduleFolders: ModuleFolder[]; // 统一的模块文件夹数据
|
||||||
mergedFolders: MergedFolder[]; // 新增合并文件夹数据
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ConfigPanel {
|
export class ConfigPanel {
|
||||||
@@ -89,18 +75,17 @@ export class ConfigPanel {
|
|||||||
private currentProjectId: string = '';
|
private currentProjectId: string = '';
|
||||||
private currentAircraftId: string = '';
|
private currentAircraftId: string = '';
|
||||||
private currentContainerId: string = '';
|
private currentContainerId: string = '';
|
||||||
private currentRepoId: string = '';
|
private currentModuleFolderId: string = '';
|
||||||
|
|
||||||
// 数据存储
|
// 数据存储
|
||||||
private projects: Project[] = [];
|
private projects: Project[] = [];
|
||||||
private aircrafts: Aircraft[] = [];
|
private aircrafts: Aircraft[] = [];
|
||||||
private containers: Container[] = [];
|
private containers: Container[] = [];
|
||||||
private configs: Config[] = [];
|
private configs: Config[] = [];
|
||||||
private gitRepos: GitRepo[] = []; // Git 仓库数据
|
private moduleFolders: ModuleFolder[] = []; // 统一的模块文件夹数据
|
||||||
private mergedFolders: MergedFolder[] = [];
|
|
||||||
|
|
||||||
// Git 文件树
|
// Git 文件树
|
||||||
private currentRepoFileTree: GitFileTree[] = [];
|
private currentModuleFolderFileTree: GitFileTree[] = [];
|
||||||
|
|
||||||
// 项目存储路径映射
|
// 项目存储路径映射
|
||||||
private projectPaths: Map<string, string> = new Map();
|
private projectPaths: Map<string, string> = new Map();
|
||||||
@@ -208,7 +193,7 @@ export class ConfigPanel {
|
|||||||
this.currentProjectId = '';
|
this.currentProjectId = '';
|
||||||
this.currentAircraftId = '';
|
this.currentAircraftId = '';
|
||||||
this.currentContainerId = '';
|
this.currentContainerId = '';
|
||||||
this.currentRepoId = '';
|
this.currentModuleFolderId = '';
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -291,24 +276,24 @@ export class ConfigPanel {
|
|||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'loadGitRepo':
|
case 'loadModuleFolder':
|
||||||
await this.loadGitRepo(data.repoId);
|
await this.loadModuleFolder(data.folderId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'syncGitRepo':
|
case 'syncGitModuleFolder':
|
||||||
await this.syncGitRepo(data.repoId);
|
await this.syncGitModuleFolder(data.folderId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'deleteGitRepo':
|
case 'deleteModuleFolder':
|
||||||
await this.deleteGitRepo(data.repoId);
|
await this.deleteModuleFolder(data.folderId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'importGitFile':
|
case 'importGitFile':
|
||||||
await this.importGitFile(data.filePath);
|
await this.importGitFile(data.filePath);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'openGitRepoInVSCode':
|
case 'openModuleFolderInVSCode':
|
||||||
await this.openTheModuleFolder('git', data.repoId);
|
await this.openTheModuleFolder(data.moduleType, data.folderId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'openConfigFileInVSCode':
|
case 'openConfigFileInVSCode':
|
||||||
@@ -320,7 +305,7 @@ export class ConfigPanel {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'deleteMergedFolder':
|
case 'deleteMergedFolder':
|
||||||
await this.deleteMergedFolder(data.folderId);
|
await this.deleteModuleFolder(data.folderId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'openMergedFolderInVSCode':
|
case 'openMergedFolderInVSCode':
|
||||||
@@ -434,9 +419,9 @@ export class ConfigPanel {
|
|||||||
// === Git 仓库管理方法 ===
|
// === Git 仓库管理方法 ===
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加 Git 仓库到容器目录
|
* 添加 Git 模块文件夹到容器目录
|
||||||
*/
|
*/
|
||||||
private async addGitRepo(url: string, name: string, branch?: string): Promise<void> {
|
private async addGitModuleFolder(url: string, name: string, branch?: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// 验证 URL
|
// 验证 URL
|
||||||
if (!url || !url.startsWith('http')) {
|
if (!url || !url.startsWith('http')) {
|
||||||
@@ -449,9 +434,9 @@ export class ConfigPanel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const repoId = 'git-' + Date.now();
|
const folderId = 'git-' + Date.now();
|
||||||
|
|
||||||
// 构建本地路径 - 在容器目录下创建分支子目录
|
// 构建本地路径
|
||||||
const container = this.containers.find(c => c.id === this.currentContainerId);
|
const container = this.containers.find(c => c.id === this.currentContainerId);
|
||||||
if (!container) {
|
if (!container) {
|
||||||
vscode.window.showErrorMessage('未找到容器');
|
vscode.window.showErrorMessage('未找到容器');
|
||||||
@@ -470,41 +455,38 @@ export class ConfigPanel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为每个分支创建独立的子目录
|
// 构建相对路径(从项目路径开始)
|
||||||
const branchName = branch || 'main';
|
const relativePath = `/${aircraft.projectId}/${aircraft.name}/${container.name}/${name}`;
|
||||||
const branchSafeName = branchName.replace(/[^a-zA-Z0-9-_]/g, '-');
|
|
||||||
const repoDirName = name;
|
|
||||||
|
|
||||||
// 路径:项目路径/飞行器名/容器名/仓库名-分支名/
|
// 完整路径用于实际操作
|
||||||
const localPath = path.join(projectPath, aircraft.name, container.name, repoDirName);
|
const localPath = path.join(projectPath, aircraft.name, container.name, name);
|
||||||
|
|
||||||
console.log(`📁 Git仓库将保存到: ${localPath}`);
|
console.log(`📁 Git模块文件夹将保存到: ${localPath}`);
|
||||||
|
console.log(`📁 相对路径: ${relativePath}`);
|
||||||
|
|
||||||
// 检查是否已存在相同 URL 和分支的仓库
|
// 检查是否已存在相同名称的模块文件夹
|
||||||
const existingRepo = this.gitRepos.find(repo =>
|
const existingFolder = this.moduleFolders.find(folder =>
|
||||||
repo.url === url && repo.branch === branchName && repo.containerId === this.currentContainerId
|
folder.name === name && folder.containerId === this.currentContainerId
|
||||||
);
|
);
|
||||||
if (existingRepo) {
|
if (existingFolder) {
|
||||||
vscode.window.showWarningMessage('该 Git 仓库和分支组合已存在');
|
vscode.window.showWarningMessage('该名称的模块文件夹已存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newRepo: GitRepo = {
|
const newFolder: ModuleFolder = {
|
||||||
id: repoId,
|
id: folderId,
|
||||||
name: `${name} (${branchName})`, // 在名称中包含分支信息
|
name: name,
|
||||||
url: url,
|
type: 'git',
|
||||||
localPath: localPath,
|
localPath: relativePath, // 存储相对路径
|
||||||
branch: branchName,
|
|
||||||
lastSync: new Date().toLocaleString(),
|
|
||||||
containerId: this.currentContainerId
|
containerId: this.currentContainerId
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(`📁 准备克隆仓库: ${name}, 分支: ${newRepo.branch}, 路径: ${localPath}`);
|
console.log(`📁 准备克隆仓库: ${name}, 分支: ${branch}, 路径: ${localPath}`);
|
||||||
|
|
||||||
// 显示进度
|
// 显示进度
|
||||||
await vscode.window.withProgress({
|
await vscode.window.withProgress({
|
||||||
location: vscode.ProgressLocation.Notification,
|
location: vscode.ProgressLocation.Notification,
|
||||||
title: `正在克隆仓库: ${name} (${newRepo.branch})`,
|
title: `正在克隆仓库: ${name}`,
|
||||||
cancellable: false
|
cancellable: false
|
||||||
}, async (progress) => {
|
}, async (progress) => {
|
||||||
progress.report({ increment: 0 });
|
progress.report({ increment: 0 });
|
||||||
@@ -545,7 +527,7 @@ export class ConfigPanel {
|
|||||||
url: url,
|
url: url,
|
||||||
singleBranch: true,
|
singleBranch: true,
|
||||||
depth: 1,
|
depth: 1,
|
||||||
ref: branchName,
|
ref: branch || 'main',
|
||||||
onProgress: (event: any) => {
|
onProgress: (event: any) => {
|
||||||
if (event.total) {
|
if (event.total) {
|
||||||
const percent = (event.loaded / event.total) * 100;
|
const percent = (event.loaded / event.total) * 100;
|
||||||
@@ -556,19 +538,19 @@ export class ConfigPanel {
|
|||||||
|
|
||||||
console.log('✅ Git克隆成功完成');
|
console.log('✅ Git克隆成功完成');
|
||||||
|
|
||||||
this.gitRepos.push(newRepo);
|
this.moduleFolders.push(newFolder);
|
||||||
await this.saveCurrentProjectData();
|
await this.saveCurrentProjectData();
|
||||||
console.log('✅ Git仓库数据已保存到项目文件');
|
console.log('✅ Git模块文件夹数据已保存到项目文件');
|
||||||
|
|
||||||
vscode.window.showInformationMessage(`Git 仓库克隆成功: ${name} (${newRepo.branch})`);
|
vscode.window.showInformationMessage(`Git 仓库克隆成功: ${name}`);
|
||||||
|
|
||||||
// 检查 Webview 状态后再加载文件树
|
// 检查 Webview 状态后再加载文件树
|
||||||
if (!this.isWebviewDisposed) {
|
if (!this.isWebviewDisposed) {
|
||||||
console.log('🌳 开始加载仓库文件树...');
|
console.log('🌳 开始加载模块文件夹文件树...');
|
||||||
// 自动加载仓库文件树
|
// 自动加载文件树
|
||||||
this.currentRepoId = repoId;
|
this.currentModuleFolderId = folderId;
|
||||||
await this.loadGitRepoFileTree(repoId);
|
await this.loadModuleFolderFileTree(folderId);
|
||||||
console.log('✅ 仓库文件树加载完成');
|
console.log('✅ 模块文件夹文件树加载完成');
|
||||||
} else {
|
} else {
|
||||||
console.log('⚠️ Webview 已被销毁,跳过文件树加载');
|
console.log('⚠️ Webview 已被销毁,跳过文件树加载');
|
||||||
}
|
}
|
||||||
@@ -580,33 +562,43 @@ export class ConfigPanel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ 在addGitRepo外部捕获错误:', error);
|
console.error('❌ 在addGitModuleFolder外部捕获错误:', error);
|
||||||
vscode.window.showErrorMessage(`添加 Git 仓库失败: ${error}`);
|
vscode.window.showErrorMessage(`添加 Git 模块文件夹失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载 Git 仓库文件树
|
* 加载模块文件夹
|
||||||
*/
|
*/
|
||||||
private async loadGitRepo(repoId: string): Promise<void> {
|
private async loadModuleFolder(folderId: string): Promise<void> {
|
||||||
this.currentRepoId = repoId;
|
this.currentModuleFolderId = folderId;
|
||||||
await this.loadGitRepoFileTree(repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
|
if (folder && folder.type === 'git') {
|
||||||
|
await this.loadModuleFolderFileTree(folderId);
|
||||||
|
}
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步 Git 仓库
|
* 同步 Git 模块文件夹
|
||||||
*/
|
*/
|
||||||
private async syncGitRepo(repoId: string): Promise<void> {
|
private async syncGitModuleFolder(folderId: string): Promise<void> {
|
||||||
const repo = this.gitRepos.find(r => r.id === repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!repo) {
|
if (!folder || folder.type !== 'git') {
|
||||||
vscode.window.showErrorMessage('未找到指定的 Git 仓库');
|
vscode.window.showErrorMessage('未找到指定的 Git 模块文件夹');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取完整路径
|
||||||
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
|
if (!fullPath) {
|
||||||
|
vscode.window.showErrorMessage('无法获取模块文件夹的完整路径');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await vscode.window.withProgress({
|
await vscode.window.withProgress({
|
||||||
location: vscode.ProgressLocation.Notification,
|
location: vscode.ProgressLocation.Notification,
|
||||||
title: `正在同步仓库: ${repo.name}`,
|
title: `正在同步仓库: ${folder.name}`,
|
||||||
cancellable: false
|
cancellable: false
|
||||||
}, async (progress) => {
|
}, async (progress) => {
|
||||||
try {
|
try {
|
||||||
@@ -616,19 +608,15 @@ export class ConfigPanel {
|
|||||||
await git.pull({
|
await git.pull({
|
||||||
fs: fs,
|
fs: fs,
|
||||||
http: http,
|
http: http,
|
||||||
dir: repo.localPath,
|
dir: fullPath,
|
||||||
author: { name: 'DCSP User', email: 'user@dcsp.local' },
|
author: { name: 'DCSP User', email: 'user@dcsp.local' },
|
||||||
fastForward: true
|
fastForward: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// 更新最后同步时间
|
|
||||||
repo.lastSync = new Date().toLocaleString();
|
|
||||||
await this.saveCurrentProjectData();
|
|
||||||
|
|
||||||
// 重新加载文件树
|
// 重新加载文件树
|
||||||
await this.loadGitRepoFileTree(repoId);
|
await this.loadModuleFolderFileTree(folderId);
|
||||||
|
|
||||||
vscode.window.showInformationMessage(`Git 仓库同步成功: ${repo.name}`);
|
vscode.window.showInformationMessage(`Git 仓库同步成功: ${folder.name}`);
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -638,14 +626,14 @@ export class ConfigPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除 Git 仓库
|
* 删除模块文件夹
|
||||||
*/
|
*/
|
||||||
private async deleteGitRepo(repoId: string): Promise<void> {
|
private async deleteModuleFolder(folderId: string): Promise<void> {
|
||||||
const repo = this.gitRepos.find(r => r.id === repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!repo) return;
|
if (!folder) return;
|
||||||
|
|
||||||
const confirm = await vscode.window.showWarningMessage(
|
const confirm = await vscode.window.showWarningMessage(
|
||||||
`确定要删除 Git 仓库 "${repo.name}" 吗?这将删除本地文件。`,
|
`确定要删除模块文件夹 "${folder.name}" 吗?这将删除本地文件。`,
|
||||||
{ modal: true },
|
{ modal: true },
|
||||||
'确定删除',
|
'确定删除',
|
||||||
'取消'
|
'取消'
|
||||||
@@ -653,45 +641,48 @@ export class ConfigPanel {
|
|||||||
|
|
||||||
if (confirm === '确定删除') {
|
if (confirm === '确定删除') {
|
||||||
try {
|
try {
|
||||||
// 删除整个仓库目录(因为是独立目录)
|
// 获取完整路径并删除文件夹
|
||||||
await fs.promises.rm(repo.localPath, { recursive: true, force: true });
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
|
if (fullPath) {
|
||||||
// 从列表中移除
|
await fs.promises.rm(fullPath, { recursive: true, force: true });
|
||||||
this.gitRepos = this.gitRepos.filter(r => r.id !== repoId);
|
|
||||||
await this.saveCurrentProjectData();
|
|
||||||
|
|
||||||
// 如果删除的是当前仓库,清空状态
|
|
||||||
if (this.currentRepoId === repoId) {
|
|
||||||
this.currentRepoId = '';
|
|
||||||
this.currentRepoFileTree = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vscode.window.showInformationMessage(`Git 仓库已删除: ${repo.name}`);
|
// 从列表中移除
|
||||||
|
this.moduleFolders = this.moduleFolders.filter(f => f.id !== folderId);
|
||||||
|
await this.saveCurrentProjectData();
|
||||||
|
|
||||||
|
// 如果删除的是当前文件夹,清空状态
|
||||||
|
if (this.currentModuleFolderId === folderId) {
|
||||||
|
this.currentModuleFolderId = '';
|
||||||
|
this.currentModuleFolderFileTree = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
vscode.window.showInformationMessage(`模块文件夹已删除: ${folder.name}`);
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
vscode.window.showErrorMessage(`删除 Git 仓库失败: ${error}`);
|
vscode.window.showErrorMessage(`删除模块文件夹失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载 Git 仓库文件树
|
* 加载模块文件夹文件树
|
||||||
*/
|
*/
|
||||||
private async loadGitRepoFileTree(repoId: string): Promise<void> {
|
private async loadModuleFolderFileTree(folderId: string): Promise<void> {
|
||||||
// 检查 Webview 是否仍然有效
|
// 检查 Webview 是否仍然有效
|
||||||
if (this.isWebviewDisposed) {
|
if (this.isWebviewDisposed) {
|
||||||
console.log('⚠️ Webview 已被销毁,跳过文件树加载');
|
console.log('⚠️ Webview 已被销毁,跳过文件树加载');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const repo = this.gitRepos.find(r => r.id === repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!repo) return;
|
if (!folder) return;
|
||||||
|
|
||||||
// 通知前端开始加载
|
// 通知前端开始加载
|
||||||
try {
|
try {
|
||||||
this.panel.webview.postMessage({
|
this.panel.webview.postMessage({
|
||||||
type: 'gitRepoLoading',
|
type: 'moduleFolderLoading',
|
||||||
loading: true
|
loading: true
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -700,16 +691,15 @@ export class ConfigPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const fileTree = await this.buildFileTree(repo.localPath);
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
this.currentRepoFileTree = fileTree;
|
if (fullPath) {
|
||||||
|
const fileTree = await this.buildFileTree(fullPath);
|
||||||
// 更新最后访问时间
|
this.currentModuleFolderFileTree = fileTree;
|
||||||
repo.lastSync = new Date().toLocaleString();
|
}
|
||||||
await this.saveCurrentProjectData();
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载仓库文件树失败:', error);
|
console.error('加载模块文件夹文件树失败:', error);
|
||||||
this.currentRepoFileTree = [];
|
this.currentModuleFolderFileTree = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 再次检查 Webview 状态
|
// 再次检查 Webview 状态
|
||||||
@@ -721,7 +711,7 @@ export class ConfigPanel {
|
|||||||
// 通知前端加载完成
|
// 通知前端加载完成
|
||||||
try {
|
try {
|
||||||
this.panel.webview.postMessage({
|
this.panel.webview.postMessage({
|
||||||
type: 'gitRepoLoading',
|
type: 'moduleFolderLoading',
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -776,14 +766,14 @@ export class ConfigPanel {
|
|||||||
* 导入 Git 文件到当前容器
|
* 导入 Git 文件到当前容器
|
||||||
*/
|
*/
|
||||||
private async importGitFile(filePath: string): Promise<void> {
|
private async importGitFile(filePath: string): Promise<void> {
|
||||||
if (!this.currentRepoId || !this.currentContainerId) {
|
if (!this.currentModuleFolderId || !this.currentContainerId) {
|
||||||
vscode.window.showErrorMessage('请先选择 Git 仓库和容器');
|
vscode.window.showErrorMessage('请先选择模块文件夹和容器');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const repo = this.gitRepos.find(r => r.id === this.currentRepoId);
|
const folder = this.moduleFolders.find(f => f.id === this.currentModuleFolderId);
|
||||||
if (!repo) {
|
if (!folder || folder.type !== 'git') {
|
||||||
vscode.window.showErrorMessage('未找到当前 Git 仓库');
|
vscode.window.showErrorMessage('未找到当前 Git 模块文件夹');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,8 +784,14 @@ export class ConfigPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const fullPath = path.join(repo.localPath, filePath);
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
const content = await fs.promises.readFile(fullPath, 'utf8');
|
if (!fullPath) {
|
||||||
|
vscode.window.showErrorMessage('无法获取模块文件夹路径');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileFullPath = path.join(fullPath, filePath);
|
||||||
|
const content = await fs.promises.readFile(fileFullPath, 'utf8');
|
||||||
const fileName = path.basename(filePath);
|
const fileName = path.basename(filePath);
|
||||||
|
|
||||||
// 创建新配置
|
// 创建新配置
|
||||||
@@ -868,11 +864,8 @@ export class ConfigPanel {
|
|||||||
const currentContainerIds = currentProjectContainers.map(c => c.id);
|
const currentContainerIds = currentProjectContainers.map(c => c.id);
|
||||||
const currentProjectConfigs = this.configs.filter(cfg => currentContainerIds.includes(cfg.containerId));
|
const currentProjectConfigs = this.configs.filter(cfg => currentContainerIds.includes(cfg.containerId));
|
||||||
|
|
||||||
// 只保存与当前项目容器相关的 Git 仓库和合并文件夹
|
// 只保存与当前项目容器相关的模块文件夹
|
||||||
const currentProjectGitRepos = this.gitRepos.filter(repo =>
|
const currentProjectModuleFolders = this.moduleFolders.filter(folder =>
|
||||||
currentContainerIds.includes(repo.containerId)
|
|
||||||
);
|
|
||||||
const currentProjectMergedFolders = this.mergedFolders.filter(folder =>
|
|
||||||
currentContainerIds.includes(folder.containerId)
|
currentContainerIds.includes(folder.containerId)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -881,18 +874,17 @@ export class ConfigPanel {
|
|||||||
aircrafts: currentProjectAircrafts,
|
aircrafts: currentProjectAircrafts,
|
||||||
containers: currentProjectContainers,
|
containers: currentProjectContainers,
|
||||||
configs: currentProjectConfigs,
|
configs: currentProjectConfigs,
|
||||||
gitRepos: currentProjectGitRepos,
|
moduleFolders: currentProjectModuleFolders // 保存模块文件夹数据
|
||||||
mergedFolders: currentProjectMergedFolders // 保存合并文件夹数据
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8Array = new TextEncoder().encode(JSON.stringify(data, null, 2));
|
const uint8Array = new TextEncoder().encode(JSON.stringify(data, null, 2));
|
||||||
await vscode.workspace.fs.writeFile(dataUri, uint8Array);
|
await vscode.workspace.fs.writeFile(dataUri, uint8Array);
|
||||||
|
|
||||||
console.log('✅ 当前项目数据已保存,包含', currentProjectGitRepos.length, '个 Git 仓库和', currentProjectMergedFolders.length, '个合并文件夹');
|
console.log('✅ 当前项目数据已保存,包含', currentProjectModuleFolders.length, '个模块文件夹');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
vscode.window.showErrorMessage(`保存项目数据失败: ${error}`);
|
vscode.window.showErrorMessage(`保存项目数据失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从项目路径加载数据
|
* 从项目路径加载数据
|
||||||
@@ -919,8 +911,7 @@ export class ConfigPanel {
|
|||||||
this.aircrafts = [];
|
this.aircrafts = [];
|
||||||
this.containers = [];
|
this.containers = [];
|
||||||
this.configs = [];
|
this.configs = [];
|
||||||
this.gitRepos = [];
|
this.moduleFolders = []; // 清空模块文件夹数据
|
||||||
this.mergedFolders = []; // 清空合并文件夹数据
|
|
||||||
|
|
||||||
// 验证数据格式并加载
|
// 验证数据格式并加载
|
||||||
if (data.projects && Array.isArray(data.projects)) {
|
if (data.projects && Array.isArray(data.projects)) {
|
||||||
@@ -935,11 +926,8 @@ export class ConfigPanel {
|
|||||||
if (data.configs && Array.isArray(data.configs)) {
|
if (data.configs && Array.isArray(data.configs)) {
|
||||||
this.configs = data.configs;
|
this.configs = data.configs;
|
||||||
}
|
}
|
||||||
if (data.gitRepos && Array.isArray(data.gitRepos)) {
|
if (data.moduleFolders && Array.isArray(data.moduleFolders)) {
|
||||||
this.gitRepos = data.gitRepos;
|
this.moduleFolders = data.moduleFolders; // 加载模块文件夹数据
|
||||||
}
|
|
||||||
if (data.mergedFolders && Array.isArray(data.mergedFolders)) {
|
|
||||||
this.mergedFolders = data.mergedFolders; // 加载合并文件夹数据
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置当前项目为第一个项目(如果有的话)
|
// 设置当前项目为第一个项目(如果有的话)
|
||||||
@@ -949,14 +937,14 @@ export class ConfigPanel {
|
|||||||
this.currentView = 'aircrafts';
|
this.currentView = 'aircrafts';
|
||||||
}
|
}
|
||||||
|
|
||||||
vscode.window.showInformationMessage(`项目数据已从 ${projectPath} 加载,包含 ${this.gitRepos.length} 个 Git 仓库和 ${this.mergedFolders.length} 个合并文件夹`);
|
vscode.window.showInformationMessage(`项目数据已从 ${projectPath} 加载,包含 ${this.moduleFolders.length} 个模块文件夹`);
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
vscode.window.showErrorMessage(`加载项目数据失败: ${error}`);
|
vscode.window.showErrorMessage(`加载项目数据失败: ${error}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查项目路径是否已存在数据
|
* 检查项目路径是否已存在数据
|
||||||
@@ -1122,8 +1110,8 @@ export class ConfigPanel {
|
|||||||
// 删除相关的配置
|
// 删除相关的配置
|
||||||
const containerIds = this.containers.filter(c => aircraftIds.includes(c.aircraftId)).map(c => c.id);
|
const containerIds = this.containers.filter(c => aircraftIds.includes(c.aircraftId)).map(c => c.id);
|
||||||
this.configs = this.configs.filter(cfg => !containerIds.includes(cfg.containerId));
|
this.configs = this.configs.filter(cfg => !containerIds.includes(cfg.containerId));
|
||||||
// 删除相关的 Git 仓库
|
// 删除相关的模块文件夹
|
||||||
this.gitRepos = this.gitRepos.filter(repo => !containerIds.includes(repo.containerId));
|
this.moduleFolders = this.moduleFolders.filter(folder => !containerIds.includes(folder.containerId));
|
||||||
// 删除项目路径映射
|
// 删除项目路径映射
|
||||||
this.projectPaths.delete(projectId);
|
this.projectPaths.delete(projectId);
|
||||||
|
|
||||||
@@ -1177,8 +1165,8 @@ export class ConfigPanel {
|
|||||||
// 删除相关的配置
|
// 删除相关的配置
|
||||||
const containerIds = this.containers.filter(c => c.aircraftId === aircraftId).map(c => c.id);
|
const containerIds = this.containers.filter(c => c.aircraftId === aircraftId).map(c => c.id);
|
||||||
this.configs = this.configs.filter(cfg => !containerIds.includes(cfg.containerId));
|
this.configs = this.configs.filter(cfg => !containerIds.includes(cfg.containerId));
|
||||||
// 删除相关的 Git 仓库
|
// 删除相关的模块文件夹
|
||||||
this.gitRepos = this.gitRepos.filter(repo => !containerIds.includes(repo.containerId));
|
this.moduleFolders = this.moduleFolders.filter(folder => !containerIds.includes(folder.containerId));
|
||||||
|
|
||||||
vscode.window.showInformationMessage(`删除飞行器: ${aircraft.name}`);
|
vscode.window.showInformationMessage(`删除飞行器: ${aircraft.name}`);
|
||||||
await this.saveCurrentProjectData();
|
await this.saveCurrentProjectData();
|
||||||
@@ -1252,8 +1240,8 @@ export class ConfigPanel {
|
|||||||
// 删除相关的配置
|
// 删除相关的配置
|
||||||
this.configs = this.configs.filter(cfg => cfg.containerId !== containerId);
|
this.configs = this.configs.filter(cfg => cfg.containerId !== containerId);
|
||||||
|
|
||||||
// 删除相关的 Git 仓库
|
// 删除相关的模块文件夹
|
||||||
this.gitRepos = this.gitRepos.filter(repo => repo.containerId !== containerId);
|
this.moduleFolders = this.moduleFolders.filter(folder => folder.containerId !== containerId);
|
||||||
|
|
||||||
vscode.window.showInformationMessage(`删除容器: ${container.name}`);
|
vscode.window.showInformationMessage(`删除容器: ${container.name}`);
|
||||||
await this.saveCurrentProjectData();
|
await this.saveCurrentProjectData();
|
||||||
@@ -1426,12 +1414,12 @@ export class ConfigPanel {
|
|||||||
console.error('❌ 获取分支失败:', error);
|
console.error('❌ 获取分支失败:', error);
|
||||||
vscode.window.showErrorMessage(`获取分支失败: ${error}`);
|
vscode.window.showErrorMessage(`获取分支失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建分支树状结构
|
* 构建分支树状结构
|
||||||
*/
|
*/
|
||||||
private buildBranchTree(branches: GitBranch[]): any[] {
|
private buildBranchTree(branches: GitBranch[]): any[] {
|
||||||
const root: any[] = [];
|
const root: any[] = [];
|
||||||
|
|
||||||
branches.forEach(branch => {
|
branches.forEach(branch => {
|
||||||
@@ -1467,7 +1455,7 @@ private buildBranchTree(branches: GitBranch[]): any[] {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async cloneBranches(url: string, branches: string[]): Promise<void> {
|
private async cloneBranches(url: string, branches: string[]): Promise<void> {
|
||||||
try {
|
try {
|
||||||
@@ -1488,7 +1476,7 @@ private buildBranchTree(branches: GitBranch[]): any[] {
|
|||||||
});
|
});
|
||||||
|
|
||||||
console.log(`📥 克隆分支: ${branch}`);
|
console.log(`📥 克隆分支: ${branch}`);
|
||||||
await this.addGitRepo(url, this.generateRepoName(url, branch), branch);
|
await this.addGitModuleFolder(url, this.generateModuleFolderName(url, branch), branch);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1500,7 +1488,7 @@ private buildBranchTree(branches: GitBranch[]): any[] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private generateRepoName(url: string, branch: string): string {
|
private generateModuleFolderName(url: string, branch: string): string {
|
||||||
const repoName = url.split('/').pop()?.replace('.git', '') || 'unknown-repo';
|
const repoName = url.split('/').pop()?.replace('.git', '') || 'unknown-repo';
|
||||||
const branchSafeName = branch.replace(/[^a-zA-Z0-9-_]/g, '-');
|
const branchSafeName = branch.replace(/[^a-zA-Z0-9-_]/g, '-');
|
||||||
return `${repoName}-${branchSafeName}`;
|
return `${repoName}-${branchSafeName}`;
|
||||||
@@ -1546,20 +1534,18 @@ private buildBranchTree(branches: GitBranch[]): any[] {
|
|||||||
case 'configs':
|
case 'configs':
|
||||||
const currentContainer = this.containers.find(c => c.id === this.currentContainerId);
|
const currentContainer = this.containers.find(c => c.id === this.currentContainerId);
|
||||||
const containerConfigs = this.configs.filter(cfg => cfg.containerId === this.currentContainerId);
|
const containerConfigs = this.configs.filter(cfg => cfg.containerId === this.currentContainerId);
|
||||||
const currentRepo = this.gitRepos.find(r => r.id === this.currentRepoId);
|
const currentModuleFolder = this.moduleFolders.find(f => f.id === this.currentModuleFolderId);
|
||||||
|
|
||||||
// 获取当前容器的 Git 仓库和合并文件夹
|
// 获取当前容器的模块文件夹
|
||||||
const containerGitRepos = this.gitRepos.filter(repo => repo.containerId === this.currentContainerId);
|
const containerModuleFolders = this.moduleFolders.filter(folder => folder.containerId === this.currentContainerId);
|
||||||
const containerMergedFolders = this.mergedFolders.filter(folder => folder.containerId === this.currentContainerId);
|
|
||||||
|
|
||||||
return this.configView.render({
|
return this.configView.render({
|
||||||
container: currentContainer,
|
container: currentContainer,
|
||||||
configs: containerConfigs,
|
configs: containerConfigs,
|
||||||
gitRepos: containerGitRepos,
|
moduleFolders: containerModuleFolders,
|
||||||
currentGitRepo: currentRepo,
|
currentModuleFolder: currentModuleFolder,
|
||||||
gitFileTree: this.currentRepoFileTree,
|
moduleFolderFileTree: this.currentModuleFolderFileTree,
|
||||||
gitLoading: false,
|
moduleFolderLoading: false
|
||||||
mergedFolders: containerMergedFolders // 传递合并文件夹数据
|
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
return this.projectView.render({
|
return this.projectView.render({
|
||||||
@@ -1567,30 +1553,31 @@ private buildBranchTree(branches: GitBranch[]): any[] {
|
|||||||
projectPaths: this.projectPaths
|
projectPaths: this.projectPaths
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async openGitRepoInVSCode(repoId: string): Promise<void> {
|
private async openGitRepoInVSCode(folderId: string): Promise<void> {
|
||||||
const repo = this.gitRepos.find(r => r.id === repoId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!repo) {
|
if (!folder) {
|
||||||
vscode.window.showErrorMessage('未找到指定的 Git 仓库');
|
vscode.window.showErrorMessage('未找到指定的模块文件夹');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 检查仓库目录是否存在
|
// 检查文件夹是否存在
|
||||||
if (!fs.existsSync(repo.localPath)) {
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
vscode.window.showErrorMessage('Git 仓库目录不存在,请重新克隆');
|
if (!fullPath || !fs.existsSync(fullPath)) {
|
||||||
|
vscode.window.showErrorMessage('模块文件夹目录不存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用 VSCode 的文件选择器让用户选择要打开的文件
|
// 使用 VSCode 的文件选择器让用户选择要打开的文件
|
||||||
const fileUri = await vscode.window.showOpenDialog({
|
const fileUri = await vscode.window.showOpenDialog({
|
||||||
defaultUri: vscode.Uri.file(repo.localPath),
|
defaultUri: vscode.Uri.file(fullPath),
|
||||||
canSelectFiles: true,
|
canSelectFiles: true,
|
||||||
canSelectFolders: false,
|
canSelectFolders: false,
|
||||||
canSelectMany: false,
|
canSelectMany: false,
|
||||||
openLabel: '选择要打开的文件',
|
openLabel: '选择要打开的文件',
|
||||||
title: `在 ${repo.name} 中选择文件`
|
title: `在 ${folder.name} 中选择文件`
|
||||||
});
|
});
|
||||||
|
|
||||||
if (fileUri && fileUri.length > 0) {
|
if (fileUri && fileUri.length > 0) {
|
||||||
@@ -1601,7 +1588,7 @@ private buildBranchTree(branches: GitBranch[]): any[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
vscode.window.showErrorMessage(`打开 Git 仓库文件失败: ${error}`);
|
vscode.window.showErrorMessage(`打开模块文件夹文件失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1653,7 +1640,7 @@ private buildBranchTree(branches: GitBranch[]): any[] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async mergeConfigs(configIds: string[], displayName: string, folderName: string): Promise<void> {
|
private async mergeConfigs(configIds: string[], displayName: string, folderName: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
if (!this.currentContainerId) {
|
if (!this.currentContainerId) {
|
||||||
vscode.window.showErrorMessage('未找到当前容器');
|
vscode.window.showErrorMessage('未找到当前容器');
|
||||||
@@ -1712,20 +1699,20 @@ private async mergeConfigs(configIds: string[], displayName: string, folderName:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 构建相对路径
|
||||||
|
const relativePath = `/${aircraft.projectId}/${aircraft.name}/${container.name}/${folderName}`;
|
||||||
|
|
||||||
// 创建合并文件夹记录
|
// 创建合并文件夹记录
|
||||||
const newFolder: MergedFolder = {
|
const newFolder: ModuleFolder = {
|
||||||
id: 'merged-' + Date.now(),
|
id: 'merged-' + Date.now(),
|
||||||
displayName: displayName, // 使用传入的显示名称
|
name: displayName,
|
||||||
folderName: folderName, // 使用传入的文件夹名称
|
type: 'merged',
|
||||||
path: mergeFolderPath,
|
localPath: relativePath,
|
||||||
fileCount: copiedFiles.length,
|
containerId: this.currentContainerId
|
||||||
containerId: this.currentContainerId,
|
|
||||||
originalConfigIds: configIds,
|
|
||||||
createdAt: new Date().toLocaleString()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加到合并文件夹列表
|
// 添加到模块文件夹列表
|
||||||
this.mergedFolders.push(newFolder);
|
this.moduleFolders.push(newFolder);
|
||||||
|
|
||||||
// 删除原始配置文件
|
// 删除原始配置文件
|
||||||
for (const configId of configIds) {
|
for (const configId of configIds) {
|
||||||
@@ -1737,19 +1724,19 @@ private async mergeConfigs(configIds: string[], displayName: string, folderName:
|
|||||||
|
|
||||||
vscode.window.showInformationMessage(`成功合并 ${selectedConfigs.length} 个配置文件到文件夹: ${folderName}`);
|
vscode.window.showInformationMessage(`成功合并 ${selectedConfigs.length} 个配置文件到文件夹: ${folderName}`);
|
||||||
|
|
||||||
// 更新UI(不自动打开文件夹)
|
// 更新UI
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ 合并配置文件失败:', error);
|
console.error('❌ 合并配置文件失败:', error);
|
||||||
vscode.window.showErrorMessage(`合并配置文件失败: ${error}`);
|
vscode.window.showErrorMessage(`合并配置文件失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部删除配置文件方法(不显示确认对话框)
|
* 内部删除配置文件方法(不显示确认对话框)
|
||||||
*/
|
*/
|
||||||
private async deleteConfigInternal(configId: string): Promise<void> {
|
private async deleteConfigInternal(configId: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const config = this.configs.find(c => c.id === configId);
|
const config = this.configs.find(c => c.id === configId);
|
||||||
if (!config) return;
|
if (!config) return;
|
||||||
@@ -1780,64 +1767,34 @@ private async deleteConfigInternal(configId: string): Promise<void> {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`删除配置文件失败: ${error}`);
|
console.error(`删除配置文件失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 删除合并文件夹
|
|
||||||
*/
|
|
||||||
private async deleteMergedFolder(folderId: string): Promise<void> {
|
|
||||||
const folder = this.mergedFolders.find(f => f.id === folderId);
|
|
||||||
if (!folder) return;
|
|
||||||
|
|
||||||
const confirm = await vscode.window.showWarningMessage(
|
|
||||||
`确定要删除合并文件夹 "${folder.displayName}" 吗?这将删除文件夹及其所有内容。`,
|
|
||||||
{ modal: true },
|
|
||||||
'确定删除',
|
|
||||||
'取消'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (confirm === '确定删除') {
|
|
||||||
try {
|
|
||||||
// 删除文件夹及其所有内容
|
|
||||||
await fs.promises.rm(folder.path, { recursive: true, force: true });
|
|
||||||
|
|
||||||
// 从列表中移除
|
|
||||||
this.mergedFolders = this.mergedFolders.filter(f => f.id !== folderId);
|
|
||||||
await this.saveCurrentProjectData();
|
|
||||||
|
|
||||||
vscode.window.showInformationMessage(`合并文件夹已删除: ${folder.displayName}`);
|
|
||||||
this.updateWebview();
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
vscode.window.showErrorMessage(`删除合并文件夹失败: ${error}`);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在 VSCode 中打开合并文件夹
|
* 在 VSCode 中打开合并文件夹
|
||||||
*/
|
*/
|
||||||
private async openMergedFolderInVSCode(folderId: string): Promise<void> {
|
private async openMergedFolderInVSCode(folderId: string): Promise<void> {
|
||||||
const folder = this.mergedFolders.find(f => f.id === folderId);
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
vscode.window.showErrorMessage('未找到指定的合并文件夹');
|
vscode.window.showErrorMessage('未找到指定的模块文件夹');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 检查文件夹是否存在
|
// 检查文件夹是否存在
|
||||||
if (!fs.existsSync(folder.path)) {
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
vscode.window.showErrorMessage('合并文件夹不存在');
|
if (!fullPath || !fs.existsSync(fullPath)) {
|
||||||
|
vscode.window.showErrorMessage('模块文件夹不存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用 VSCode 打开文件夹
|
// 使用 VSCode 打开文件夹
|
||||||
const folderUri = vscode.Uri.file(folder.path);
|
const folderUri = vscode.Uri.file(fullPath);
|
||||||
vscode.commands.executeCommand('vscode.openFolder', folderUri, { forceNewWindow: false });
|
vscode.commands.executeCommand('vscode.openFolder', folderUri, { forceNewWindow: false });
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
vscode.window.showErrorMessage(`打开合并文件夹失败: ${error}`);
|
vscode.window.showErrorMessage(`打开模块文件夹失败: ${error}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一方法:在 VSCode 中打开模块文件夹中的文件
|
* 统一方法:在 VSCode 中打开模块文件夹中的文件
|
||||||
@@ -1845,47 +1802,28 @@ private async openMergedFolderInVSCode(folderId: string): Promise<void> {
|
|||||||
* @param id 模块 ID
|
* @param id 模块 ID
|
||||||
*/
|
*/
|
||||||
private async openTheModuleFolder(type: 'git' | 'merged', id: string): Promise<void> {
|
private async openTheModuleFolder(type: 'git' | 'merged', id: string): Promise<void> {
|
||||||
let folderPath: string | undefined;
|
const folder = this.moduleFolders.find(f => f.id === id);
|
||||||
let folderName: string | undefined;
|
|
||||||
|
|
||||||
if (type === 'git') {
|
|
||||||
const repo = this.gitRepos.find(r => r.id === id);
|
|
||||||
if (!repo) {
|
|
||||||
vscode.window.showErrorMessage('未找到指定的 Git 仓库');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
folderPath = repo.localPath;
|
|
||||||
folderName = repo.name;
|
|
||||||
} else if (type === 'merged') {
|
|
||||||
const folder = this.mergedFolders.find(f => f.id === id);
|
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
vscode.window.showErrorMessage('未找到指定的合并文件夹');
|
vscode.window.showErrorMessage('未找到指定的模块文件夹');
|
||||||
return;
|
|
||||||
}
|
|
||||||
folderPath = folder.path;
|
|
||||||
folderName = folder.displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!folderPath) {
|
|
||||||
vscode.window.showErrorMessage('未找到文件夹路径');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 检查文件夹是否存在
|
// 检查文件夹是否存在
|
||||||
if (!fs.existsSync(folderPath)) {
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
vscode.window.showErrorMessage(`${type === 'git' ? 'Git 仓库' : '合并文件夹'}目录不存在`);
|
if (!fullPath || !fs.existsSync(fullPath)) {
|
||||||
|
vscode.window.showErrorMessage('模块文件夹目录不存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用 VSCode 的文件选择器让用户选择要打开的文件
|
// 使用 VSCode 的文件选择器让用户选择要打开的文件
|
||||||
const fileUri = await vscode.window.showOpenDialog({
|
const fileUri = await vscode.window.showOpenDialog({
|
||||||
defaultUri: vscode.Uri.file(folderPath),
|
defaultUri: vscode.Uri.file(fullPath),
|
||||||
canSelectFiles: true,
|
canSelectFiles: true,
|
||||||
canSelectFolders: false,
|
canSelectFolders: false,
|
||||||
canSelectMany: false,
|
canSelectMany: false,
|
||||||
openLabel: '选择要打开的文件',
|
openLabel: '选择要打开的文件',
|
||||||
title: `在 ${folderName} 中选择文件`
|
title: `在 ${folder.name} 中选择文件`
|
||||||
});
|
});
|
||||||
|
|
||||||
if (fileUri && fileUri.length > 0) {
|
if (fileUri && fileUri.length > 0) {
|
||||||
@@ -1896,7 +1834,28 @@ private async openMergedFolderInVSCode(folderId: string): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
vscode.window.showErrorMessage(`打开${type === 'git' ? 'Git 仓库' : '合并文件夹'}文件失败: ${error}`);
|
vscode.window.showErrorMessage(`打开模块文件夹文件失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模块文件夹的完整路径
|
||||||
|
*/
|
||||||
|
private getModuleFolderFullPath(folder: ModuleFolder): string | null {
|
||||||
|
const container = this.containers.find(c => c.id === folder.containerId);
|
||||||
|
if (!container) return null;
|
||||||
|
|
||||||
|
const aircraft = this.aircrafts.find(a => a.id === container.aircraftId);
|
||||||
|
if (!aircraft) return null;
|
||||||
|
|
||||||
|
const projectPath = this.projectPaths.get(aircraft.projectId);
|
||||||
|
if (!projectPath) return null;
|
||||||
|
|
||||||
|
// 从相对路径解析出文件夹名称
|
||||||
|
const pathParts = folder.localPath.split('/').filter(part => part);
|
||||||
|
if (pathParts.length < 4) return null;
|
||||||
|
|
||||||
|
const folderName = pathParts[pathParts.length - 1];
|
||||||
|
return path.join(projectPath, aircraft.name, container.name, folderName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,7 @@ export interface Container {
|
|||||||
name: string;
|
name: string;
|
||||||
aircraftId: string;
|
aircraftId: string;
|
||||||
configs: Config[];
|
configs: Config[];
|
||||||
|
moduleFolders: ModuleFolder[]; // 新增:模块文件夹列表
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
@@ -25,3 +26,12 @@ export interface Config {
|
|||||||
content: string;
|
content: string;
|
||||||
containerId: string;
|
containerId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增:统一的模块文件夹接口
|
||||||
|
export interface ModuleFolder {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
type: 'git' | 'merged'; // 类型标识
|
||||||
|
localPath: string; // 相对路径,如 "/项目1/飞行器1/容器1/test-code"
|
||||||
|
containerId: string;
|
||||||
|
}
|
||||||
45
src/panels/types/DataTypes.ts
Normal file
45
src/panels/types/DataTypes.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// src/types/DataTypes.ts
|
||||||
|
|
||||||
|
// 统一的模块文件夹接口
|
||||||
|
export interface ModuleFolder {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
type: 'git' | 'merged'; // 类型标识
|
||||||
|
localPath: string; // 相对路径,如 "/项目1/飞行器1/容器1/test-code"
|
||||||
|
containerId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目数据接口
|
||||||
|
export interface ProjectData {
|
||||||
|
projects: Project[];
|
||||||
|
aircrafts: Aircraft[];
|
||||||
|
containers: Container[];
|
||||||
|
configs: Config[];
|
||||||
|
moduleFolders: ModuleFolder[]; // 统一的模块文件夹数据
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基础数据接口
|
||||||
|
export interface Project {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Aircraft {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
projectId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Container {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
aircraftId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Config {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
fileName: string;
|
||||||
|
content: string;
|
||||||
|
containerId: string;
|
||||||
|
}
|
||||||
9
src/panels/types/ViewTypes.ts
Normal file → Executable file
9
src/panels/types/ViewTypes.ts
Normal file → Executable file
@@ -39,14 +39,13 @@ export interface ContainerConfigData {
|
|||||||
configs: ConfigViewData[];
|
configs: ConfigViewData[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增 Git 相关类型
|
// 新增模块文件夹相关类型
|
||||||
export interface GitRepoData {
|
export interface ModuleFolderData {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
type: 'git' | 'merged';
|
||||||
localPath: string;
|
localPath: string;
|
||||||
branch: string;
|
containerId: string;
|
||||||
lastSync: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GitFileTree {
|
export interface GitFileTree {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { BaseView } from './BaseView';
|
import { BaseView } from './BaseView';
|
||||||
import { ContainerConfigData, ConfigViewData } from '../types/ViewTypes';
|
import { ContainerConfigData, ConfigViewData } from '../types/ViewTypes';
|
||||||
|
import { ModuleFolder } from '../types/DataTypes';
|
||||||
|
|
||||||
// Git 分支接口
|
// Git 分支接口
|
||||||
interface GitBranch {
|
interface GitBranch {
|
||||||
@@ -26,29 +27,6 @@ interface GitFileTree {
|
|||||||
children?: GitFileTree[];
|
children?: GitFileTree[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Git 仓库接口
|
|
||||||
interface GitRepo {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
localPath: string;
|
|
||||||
branch: string;
|
|
||||||
lastSync: string;
|
|
||||||
containerId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并文件夹接口
|
|
||||||
interface MergedFolder {
|
|
||||||
id: string;
|
|
||||||
displayName: string; // 配置栏显示的名称
|
|
||||||
folderName: string; // 实际文件夹名称
|
|
||||||
path: string;
|
|
||||||
fileCount: number;
|
|
||||||
containerId: string;
|
|
||||||
originalConfigIds: string[];
|
|
||||||
createdAt: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 树状分支节点接口
|
// 树状分支节点接口
|
||||||
interface BranchTreeNode {
|
interface BranchTreeNode {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -62,25 +40,23 @@ interface BranchTreeNode {
|
|||||||
|
|
||||||
export class ConfigView extends BaseView {
|
export class ConfigView extends BaseView {
|
||||||
render(data?: ContainerConfigData & {
|
render(data?: ContainerConfigData & {
|
||||||
gitRepos?: GitRepo[];
|
moduleFolders?: ModuleFolder[];
|
||||||
currentGitRepo?: GitRepo;
|
currentModuleFolder?: ModuleFolder;
|
||||||
gitFileTree?: GitFileTree[];
|
moduleFolderFileTree?: GitFileTree[];
|
||||||
gitLoading?: boolean;
|
moduleFolderLoading?: boolean;
|
||||||
gitBranches?: GitBranch[];
|
gitBranches?: GitBranch[];
|
||||||
gitRepoUrl?: string;
|
gitRepoUrl?: string;
|
||||||
mergedFolders?: MergedFolder[];
|
|
||||||
}): string {
|
}): string {
|
||||||
const container = data?.container;
|
const container = data?.container;
|
||||||
const configs = data?.configs || [];
|
const configs = data?.configs || [];
|
||||||
const gitRepos = data?.gitRepos || [];
|
const moduleFolders = data?.moduleFolders || [];
|
||||||
const currentGitRepo = data?.currentGitRepo;
|
const currentModuleFolder = data?.currentModuleFolder;
|
||||||
const gitFileTree = data?.gitFileTree || [];
|
const moduleFolderFileTree = data?.moduleFolderFileTree || [];
|
||||||
const gitLoading = data?.gitLoading || false;
|
const moduleFolderLoading = data?.moduleFolderLoading || false;
|
||||||
const gitBranches = data?.gitBranches || [];
|
const gitBranches = data?.gitBranches || [];
|
||||||
const gitRepoUrl = data?.gitRepoUrl || '';
|
const gitRepoUrl = data?.gitRepoUrl || '';
|
||||||
const mergedFolders = data?.mergedFolders || [];
|
|
||||||
|
|
||||||
// 生成配置列表的 HTML - 包含配置文件和 Git 仓库
|
// 生成配置列表的 HTML - 包含配置文件和模块文件夹
|
||||||
const configsHtml = configs.map((config: ConfigViewData) => `
|
const configsHtml = configs.map((config: ConfigViewData) => `
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@@ -96,41 +72,23 @@ export class ConfigView extends BaseView {
|
|||||||
</tr>
|
</tr>
|
||||||
`).join('');
|
`).join('');
|
||||||
|
|
||||||
// 生成合并文件夹的 HTML - 显示在配置列表中
|
// 生成模块文件夹的 HTML - 统一显示 Git 和合并文件夹
|
||||||
const mergedFoldersHtml = mergedFolders.map((folder: MergedFolder) => `
|
const moduleFoldersHtml = moduleFolders.map((folder: ModuleFolder) => {
|
||||||
<tr>
|
const icon = folder.type === 'git' ? '📁' : '📁';
|
||||||
<td>
|
|
||||||
<span class="editable">📁 ${folder.displayName}</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="clickable" onclick="openTheModuleFolder('${folder.id}', 'merged')">${folder.folderName}</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn-delete" onclick="deleteMergedFolder('${folder.id}')">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
`).join('');
|
|
||||||
|
|
||||||
// 生成 Git 仓库列表的 HTML - 修改显示方式,Git 仓库不可勾选
|
|
||||||
const gitReposHtml = gitRepos.map(repo => {
|
|
||||||
// 提取仓库名称(从URL中获取或使用name)
|
|
||||||
const repoName = repo.name.split(' (')[0]; // 移除分支名部分
|
|
||||||
// 提取分支名
|
|
||||||
const branchMatch = repo.name.match(/\(([^)]+)\)/);
|
|
||||||
const branchName = branchMatch ? branchMatch[1] : repo.branch;
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span class="editable">📁 ${repoName}</span>
|
<span class="editable">${icon} ${folder.name}</span>
|
||||||
<div style="font-size: 12px; color: var(--vscode-descriptionForeground); margin-top: 4px;">
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="clickable" onclick="openTheModuleFolder('${repo.id}', 'git')">${branchName}</span>
|
<span class="clickable" onclick="openTheModuleFolder('${folder.id}', '${folder.type}')">${folder.localPath.split('/').pop()}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn-delete" onclick="deleteGitRepo('${repo.id}')">删除</button>
|
${folder.type === 'git' ? `
|
||||||
|
<button class="btn-sync" onclick="syncModuleFolder('${folder.id}')" style="margin-right: 5px;">同步</button>
|
||||||
|
` : ''}
|
||||||
|
<button class="btn-delete" onclick="deleteModuleFolder('${folder.id}')">删除</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
@@ -182,6 +140,19 @@ export class ConfigView extends BaseView {
|
|||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-sync {
|
||||||
|
background: var(--vscode-button-background);
|
||||||
|
color: var(--vscode-button-foreground);
|
||||||
|
padding: 4px 8px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sync:hover {
|
||||||
|
background: var(--vscode-button-hoverBackground);
|
||||||
|
}
|
||||||
|
|
||||||
/* 树状分支样式 */
|
/* 树状分支样式 */
|
||||||
.branch-tree {
|
.branch-tree {
|
||||||
font-family: 'Courier New', monospace;
|
font-family: 'Courier New', monospace;
|
||||||
@@ -323,21 +294,20 @@ export class ConfigView extends BaseView {
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="30%">配置</th>
|
<th width="30%">配置</th>
|
||||||
<th width="40%">文件</th>
|
<th width="40%">文件/文件夹</th>
|
||||||
<th width="30%">操作</th>
|
<th width="30%">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
${configsHtml}
|
${configsHtml}
|
||||||
${mergedFoldersHtml}
|
${moduleFoldersHtml}
|
||||||
${gitReposHtml}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Git 仓库管理部分 -->
|
<!-- 模块文件夹管理部分 -->
|
||||||
<div class="config-section">
|
<div class="config-section">
|
||||||
<h3 class="section-title">📚 Git 仓库管理</h3>
|
<h3 class="section-title">📚 模块云仓库</h3>
|
||||||
|
|
||||||
<!-- URL 输入区域 -->
|
<!-- URL 输入区域 -->
|
||||||
<div class="url-input-section">
|
<div class="url-input-section">
|
||||||
@@ -391,8 +361,7 @@ export class ConfigView extends BaseView {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 统一功能:打开模块文件夹
|
||||||
// 统一功能:打开模块文件夹(合并 Git 仓库和合并文件夹功能)
|
|
||||||
function openTheModuleFolder(id, type) {
|
function openTheModuleFolder(id, type) {
|
||||||
console.log('📂 打开模块文件夹:', { id, type });
|
console.log('📂 打开模块文件夹:', { id, type });
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
@@ -436,46 +405,34 @@ export class ConfigView extends BaseView {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除合并文件夹功能
|
// 删除模块文件夹功能
|
||||||
function deleteMergedFolder(folderId) {
|
function deleteModuleFolder(folderId) {
|
||||||
console.log('🗑️ 尝试删除合并文件夹:', folderId);
|
console.log('🗑️ 尝试删除模块文件夹:', folderId);
|
||||||
|
|
||||||
showConfirmDialog(
|
showConfirmDialog(
|
||||||
'确认删除合并文件夹',
|
'确认删除模块文件夹',
|
||||||
'确定删除这个合并文件夹吗?这将删除文件夹及其所有内容。',
|
'确定删除这个模块文件夹吗?这将删除文件夹及其所有内容。',
|
||||||
function() {
|
function() {
|
||||||
console.log('✅ 用户确认删除合并文件夹:', folderId);
|
console.log('✅ 用户确认删除模块文件夹:', folderId);
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
type: 'deleteMergedFolder',
|
type: 'deleteModuleFolder',
|
||||||
folderId: folderId
|
folderId: folderId
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
// 用户取消删除
|
// 用户取消删除
|
||||||
console.log('❌ 用户取消删除合并文件夹');
|
console.log('❌ 用户取消删除模块文件夹');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Git 仓库删除功能
|
// 同步 Git 模块文件夹
|
||||||
function deleteGitRepo(repoId) {
|
function syncModuleFolder(folderId) {
|
||||||
console.log('🗑️ 尝试删除 Git 仓库:', repoId);
|
console.log('🔄 同步模块文件夹:', folderId);
|
||||||
|
|
||||||
showConfirmDialog(
|
|
||||||
'确认删除 Git 仓库',
|
|
||||||
'确定删除这个 Git 仓库吗?这将删除本地克隆的代码文件夹。',
|
|
||||||
function() {
|
|
||||||
console.log('✅ 用户确认删除 Git 仓库:', repoId);
|
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
type: 'deleteGitRepo',
|
type: 'syncGitModuleFolder',
|
||||||
repoId: repoId
|
folderId: folderId
|
||||||
});
|
});
|
||||||
},
|
|
||||||
function() {
|
|
||||||
// 用户取消删除
|
|
||||||
console.log('❌ 用户取消删除 Git 仓库');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function goBackToContainers() {
|
function goBackToContainers() {
|
||||||
@@ -552,14 +509,6 @@ export class ConfigView extends BaseView {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncGitRepo(repoId) {
|
|
||||||
console.log('🔄 同步仓库:', repoId);
|
|
||||||
vscode.postMessage({
|
|
||||||
type: 'syncGitRepo',
|
|
||||||
repoId: repoId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置文件合并功能
|
// 配置文件合并功能
|
||||||
function toggleConfigSelection(configId) {
|
function toggleConfigSelection(configId) {
|
||||||
const checkbox = document.querySelector('.config-checkbox[data-id="' + configId + '"]');
|
const checkbox = document.querySelector('.config-checkbox[data-id="' + configId + '"]');
|
||||||
|
|||||||
Reference in New Issue
Block a user