diff --git a/frontend/app/components/ContentArea.vue b/frontend/app/components/ContentArea.vue index e10172a..e2d659b 100644 --- a/frontend/app/components/ContentArea.vue +++ b/frontend/app/components/ContentArea.vue @@ -31,6 +31,9 @@ import { GlobalOutlined, SaveOutlined, DownloadOutlined, + SearchOutlined, + WarningOutlined, + StopOutlined, } from '@ant-design/icons-vue' import { Modal, message } from 'ant-design-vue' import { AppService } from '../../bindings/github.com/zhuy1228/GitPilot/internal/app' @@ -100,6 +103,21 @@ const showSettings = ref(false) const settingsLoading = ref(false) const gitConfig = ref({ userName: '', userEmail: '' }) +// ---- 冲突处理 ---- +const isMerging = ref(false) +const conflictFiles = ref([]) +const selectedConflictFile = ref(null) +const conflictContent = ref('') +const conflictSaving = ref(false) + +// ---- 提交搜索 ---- +const searchKeyword = ref('') +const searchAuthor = ref('') +const searchLoading = ref(false) +const isSearchMode = ref(false) +const searchResults = ref([]) +const displayLogs = computed(() => isSearchMode.value ? searchResults.value : commitLogs.value) + // ---- 文件列表拖拽调整宽度 ---- const fileListWidth = ref(300) const MIN_FILELIST = 180 @@ -256,6 +274,20 @@ async function loadStatus() { loadingFiles.value = false } + // 检查合并冲突状态 + try { + isMerging.value = await AppService.IsMerging(props.project.path) + if (isMerging.value) { + const cFiles = await AppService.GetConflictFiles(props.project.path) + conflictFiles.value = Array.isArray(cFiles) ? cFiles : [] + } else { + conflictFiles.value = [] + selectedConflictFile.value = null + } + } catch (e) { + console.error('检查合并状态失败:', e) + } + // 第三步:并行加载分支列表 + 提交历史 loadBranches() if (activeTab.value === 'history') { @@ -794,6 +826,122 @@ async function saveSettings() { } } +// ---- 冲突处理 ---- +async function selectConflictFile(file) { + selectedConflictFile.value = file + conflictContent.value = '' + try { + const content = await AppService.GetConflictFileContent(props.project.path, file.filePath) + conflictContent.value = content + } catch (e) { + conflictContent.value = '读取冲突文件失败: ' + e + } +} + +async function saveConflictContent() { + if (!selectedConflictFile.value) return + conflictSaving.value = true + try { + await AppService.SaveConflictFile(props.project.path, selectedConflictFile.value.filePath, conflictContent.value) + message.success('冲突文件已保存') + } catch (e) { + Modal.error({ title: '保存失败', content: String(e) }) + } finally { + conflictSaving.value = false + } +} + +async function resolveConflictFiles(files) { + if (!props.project?.path) return + try { + const paths = files.map(f => f.filePath) + await AppService.ResolveConflictFile(props.project.path, paths) + message.success('已标记为已解决') + isMerging.value = await AppService.IsMerging(props.project.path) + if (isMerging.value) { + const cFiles = await AppService.GetConflictFiles(props.project.path) + conflictFiles.value = Array.isArray(cFiles) ? cFiles : [] + } else { + conflictFiles.value = [] + } + selectedConflictFile.value = null + await refreshFiles() + } catch (e) { + Modal.error({ title: '解决冲突失败', content: String(e) }) + } +} + +async function completeMerge() { + if (!props.project?.path) return + const msg = commitMessage.value.trim() || 'Merge completed' + commitLoading.value = true + try { + await AppService.CommitChanges(props.project.path, msg) + commitMessage.value = '' + isMerging.value = false + conflictFiles.value = [] + selectedConflictFile.value = null + await loadStatus() + } catch (e) { + Modal.error({ title: '完成合并失败', content: String(e) }) + } finally { + commitLoading.value = false + } +} + +async function handleAbortMerge() { + if (!props.project?.path) return + Modal.confirm({ + title: '确认中止合并', + icon: h(ExclamationCircleOutlined), + content: '中止合并将丢弃所有合并更改,回到合并之前的状态。确定继续?', + okText: '中止合并', + cancelText: '取消', + okButtonProps: { danger: true }, + async onOk() { + try { + await AppService.AbortMerge(props.project.path) + message.success('已中止合并') + isMerging.value = false + conflictFiles.value = [] + selectedConflictFile.value = null + await loadStatus() + } catch (e) { + Modal.error({ title: '中止合并失败', content: String(e) }) + } + }, + }) +} + +// ---- 提交搜索 ---- +async function searchCommits() { + if (!props.project?.path) return + if (!searchKeyword.value.trim() && !searchAuthor.value.trim()) return + searchLoading.value = true + isSearchMode.value = true + try { + const results = await AppService.SearchCommitLog( + props.project.path, + searchKeyword.value.trim(), + searchAuthor.value.trim(), + 100 + ) + searchResults.value = Array.isArray(results) ? results : [] + } catch (e) { + console.error('搜索提交失败:', e) + searchResults.value = [] + } finally { + searchLoading.value = false + } +} + +function clearSearch() { + isSearchMode.value = false + searchKeyword.value = '' + searchAuthor.value = '' + searchResults.value = [] +} + // ---- 提交历史 ---- async function loadCommitLog() { if (!props.project?.path) return @@ -1237,6 +1385,57 @@ watch(activeTab, (tab) => { + +
+
+ + 合并冲突 + + {{ conflictFiles.length }} 个文件需要解决 + + + + + + 中止 + + + 完成合并 + + +
+
+
+ + {{ cf.filePath }} +
+ + + + + +
+
+
+
+ + 全部标记为已解决 + +
+
+