0
0

给项目页面、飞行器页面

This commit is contained in:
xubing
2025-12-05 21:15:33 +08:00
parent 2c314b9b0b
commit 46c184b920
18 changed files with 498 additions and 57 deletions

View File

@@ -116,7 +116,7 @@ class ConfigPanel {
return this.openRepoSelectForScope('config');
}
/**
* 弹出“上传代码”时的仓库 + 分支选择弹窗
* 弹出“上传代码”时的仓库 + 分支选择弹窗 (模块文件夹专用)
*/
async openUploadRepoSelect(folderId, folderType) {
await this.loadRepoConfigs();
@@ -133,6 +133,24 @@ class ConfigPanel {
folderType
});
}
/**
* 弹出“上传代码”时的仓库 + 分支选择弹窗 (Project/Aircraft/Container 专用)
*/
async openUploadRepoSelectForScope(scope, id) {
await this.loadRepoConfigs();
if (this.repoConfigs.length === 0) {
vscode.window.showWarningMessage('尚未配置任何仓库,请先点击右上角 "仓库配置" 按钮编辑 dcsp-repos.json。');
return;
}
if (this.isWebviewDisposed)
return;
this.panel.webview.postMessage({
type: 'showUploadRepoSelect',
repos: this.repoConfigs.map(r => ({ name: r.name })),
folderId: id,
folderType: scope // 传递 scope 作为类型
});
}
/**
* “获取仓库”弹窗确认后:用于拉取分支
*/
@@ -147,9 +165,11 @@ class ConfigPanel {
await this.fetchBranchesForRepo(repo);
}
/**
* “上传代码”弹窗确认后:根据 folderType 决定上传逻辑,并使用用户输入的 branchName
* “上传代码”弹窗确认后:根据 type 决定上传逻辑,并使用用户输入的 branchName
*/
async handleUploadRepoSelected(folderId, folderType, repoName, branchName) {
async handleUploadRepoSelected(id, // 现在是通用 ID (folderId, projectId, aircraftId, containerId)
type, // 扩展类型
repoName, branchName) {
const trimmedBranch = (branchName || '').trim();
if (!trimmedBranch) {
vscode.window.showErrorMessage('分支名称不能为空');
@@ -161,13 +181,17 @@ class ConfigPanel {
vscode.window.showErrorMessage(`在仓库配置中未找到名为 "${repoName}" 的仓库`);
return;
}
if (folderType === 'local') {
// 本地模块 -> 选中仓库 + 指定分支
await this.uploadLocalModuleFolder(folderId, repo.url, trimmedBranch, repo.username, repo.token);
if (type === 'local') {
// 本地模块 -> 选中仓库 + 指定分支 (原逻辑)
await this.uploadLocalModuleFolder(id, repo.url, trimmedBranch, repo.username, repo.token);
}
else if (type === 'git') {
// Git 模块 -> 选中仓库 + 指定分支 (原逻辑)
await this.processGitUploadWithBranch(id, repo, trimmedBranch);
}
else {
// Git 模块 -> 选中仓库 + 指定分支
await this.processGitUploadWithBranch(folderId, repo, trimmedBranch);
// 新增逻辑Project, Aircraft, Container 上传
await this.uploadProjectAircraftContainer(id, type, repo, trimmedBranch);
}
}
/**
@@ -201,6 +225,7 @@ class ConfigPanel {
}, async (progress) => {
try {
progress.report({ increment: 0, message: '准备上传...' });
// 这里使用 GitService.pushToRepoUrl它负责 checkout 和 push
await GitService_1.GitService.pushToRepoUrl(fullPath, repo.url, branchName, repo.username, repo.token);
this.projectService.updateModuleFolder(folderId, {
uploaded: true,
@@ -285,13 +310,18 @@ class ConfigPanel {
'importGitFile': (data) => this.importGitFile(data.filePath),
'openTheModuleFolder': (data) => this.openTheModuleFolder(data.moduleType, data.id),
'renameModuleFolder': (data) => this.renameModuleFolder(data.folderId, data.newName),
// 上传功能
// 模块上传功能 (原逻辑)
'uploadGitModuleFolder': (data) => this.uploadGitModuleFolder(data.folderId, data.username, data.password),
'openRepoSelectForUpload': (data) => this.openUploadRepoSelect(data.folderId, 'local'),
'uploadLocalModuleFolder': (data) => this.uploadLocalModuleFolder(data.folderId, data.repoUrl, data.branchName),
'openRepoSelectForGitUpload': (data) => this.openUploadRepoSelect(data.folderId, 'git'),
// 上传时 仓库+分支 选择确认
'uploadRepoSelected': (data) => this.handleUploadRepoSelected(data.folderId, data.folderType, data.repoName, data.branchName)
// 新增Project/Aircraft/Container 上传
'openRepoSelectForProjectUpload': (data) => this.openUploadRepoSelectForScope('project', data.projectId),
'openRepoSelectForAircraftUpload': (data) => this.openUploadRepoSelectForScope('aircraft', data.aircraftId),
'openRepoSelectForContainerUpload': (data) => this.openUploadRepoSelectForScope('container', data.containerId),
// 统一的上传时 仓库+分支 选择确认
'uploadRepoSelected': (data) => this.handleUploadRepoSelected(data.folderId, data.folderType, // 此时 data.folderType 可能是 'project' | 'aircraft' | 'container'
data.repoName, data.branchName)
};
const handler = messageHandlers[data.type];
if (handler) {
@@ -1072,6 +1102,87 @@ class ConfigPanel {
// =============================================
// 上传功能方法
// =============================================
/**
* 上传 Project / Aircraft / Container 目录到 Git 仓库
*/
async uploadProjectAircraftContainer(id, type, repo, branchName) {
let fullPath = null;
let name = '';
// 1. 获取目标目录的完整路径和名称
if (type === 'project') {
fullPath = this.projectService.getProjectPath(id) || null;
name = this.projectService.getProjects().find(p => p.id === id)?.name || 'Project';
}
else if (type === 'aircraft') {
const aircraft = this.projectService.getAircraftsByProject(this.currentProjectId).find(a => a.id === id);
name = aircraft?.name || 'Aircraft';
if (aircraft) {
fullPath = path.join(this.projectService.getProjectPath(aircraft.projectId) || '', aircraft.name);
}
}
else if (type === 'container') {
const container = this.projectService.getContainersByAircraft(this.currentAircraftId).find(c => c.id === id);
name = container?.name || 'Container';
if (container) {
const aircraft = this.projectService.getAircraftsByProject(this.currentProjectId).find(a => a.id === container.aircraftId);
if (aircraft) {
fullPath = path.join(this.projectService.getProjectPath(aircraft.projectId) || '', aircraft.name, container.name);
}
}
}
if (!fullPath || !require('fs').existsSync(fullPath)) {
vscode.window.showErrorMessage(`无法获取 ${type} "${name}" 的有效路径或目录不存在。请先配置项目路径并确保目录存在。`);
return;
}
await vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: `正在上传 ${type}: ${name}`,
cancellable: false
}, async (progress) => {
try {
progress.report({ increment: 0, message: '检查目录...' });
const fs = require('fs');
// 检查目录是否为空
const dirContents = await fs.promises.readdir(fullPath);
if (dirContents.length === 0) {
throw new Error('目录为空,无法上传');
}
// 2. 检查是否为 Git 仓库并初始化
let isGitRepo = false;
try {
// Check for .git directory
if (fs.existsSync(path.join(fullPath, '.git'))) {
isGitRepo = true;
}
}
catch (e) { /* ignore */ }
if (!isGitRepo) {
progress.report({ increment: 10, message: '初始化 Git 仓库...' });
// initRepository 内部会创建并切换到指定分支
await GitService_1.GitService.initRepository(fullPath, branchName);
}
// 3. 配置远程仓库
progress.report({ increment: 20, message: '配置远程仓库...' });
try {
// 尝试移除旧的 origin 远程,以避免冲突
await GitService_1.GitService.removeRemote(fullPath);
}
catch (e) { /* ignore if no remote */ }
await GitService_1.GitService.addRemote(fullPath, repo.url, repo.username, repo.token);
// 4. 提交并推送
progress.report({ increment: 40, message: '提交并推送到远程仓库...' });
// commitAndPushToBranch 内部会 add, commit, checkout -B, push
await GitService_1.GitService.commitAndPushToBranch(fullPath, branchName, repo.url, repo.username, repo.token);
progress.report({ increment: 100, message: '完成' });
vscode.window.showInformationMessage(`${type} ${name} 已成功上传到 ${repo.name} 的分支 ${branchName}`);
this.updateWebview();
}
catch (error) {
console.error(`${type} 上传失败:`, error);
vscode.window.showErrorMessage(`推送失败: ${error.message || error}`);
}
});
}
async uploadGitModuleFolder(folderId, username, password) {
const folder = this.projectService.getModuleFolder(folderId);
if (!folder || folder.type !== 'git') {