feat: 添加文件选择和自动查找功能,优化模板创建界面

This commit is contained in:
zhanggy committed 2025-10-28 14:00:16 +08:00
1 parent de7af2f650
commit d6d86e5042
4 files changed
+174 -46

No files matched your search

+120 -42
View File
@@ -196,7 +196,7 @@
<!-- Add File Dialog -->
<v-dialog
v-model="showFileDialog"
max-width="500"
max-width="600"
>
<v-card>
<v-card-title>添加文件</v-card-title>
@@ -204,14 +204,52 @@
<v-form v-model="fileFormValid">
<v-text-field
v-model="newFilePath"
label="文件路径 *"
label="目标文件路径 *"
placeholder="例如: src/index.js"
:rules="[requiredRule]"
required
density="comfortable"
ref="fileInputRef"
@keydown.enter="confirmAddFile"
@keydown.enter="selectAndAddFile"
/>
<div class="d-flex align-center my-4">
<v-btn
@click="selectSourceFile"
variant="outlined"
class="mr-2"
>
选择文件
</v-btn>
<v-btn
@click="selectSourceFolder"
variant="outlined"
class="mr-2"
>
选择文件夹
</v-btn>
</div>
<!-- Display selected source -->
<div v-if="selectedSourcePath" class="d-flex align-center">
<v-icon :color="isAutoFindMode ? 'warning' : 'info'" class="mr-2">
{{ isAutoFindMode ? 'mdi-folder' : 'mdi-file' }}
</v-icon>
<span class="text-truncate">{{ selectedSourcePath }}</span>
</div>
<!-- Auto-find indicator -->
<v-alert
v-if="isAutoFindMode"
type="info"
variant="tonal"
class="mt-2"
>
<div class="d-flex align-center">
<v-icon class="mr-2">mdi-auto-fix</v-icon>
<span>自动寻找文件夹内的文件</span>
</div>
</v-alert>
</v-form>
</v-card-text>
<v-card-actions>
@@ -219,10 +257,10 @@
<v-btn @click="showFileDialog = false"> 取消 </v-btn>
<v-btn
color="primary"
@click="confirmAddFile"
:disabled="!fileFormValid"
@click="selectAndAddFile"
:disabled="!fileFormValid || !selectedSourcePath"
>
添加并编辑
添加
</v-btn>
</v-card-actions>
</v-card>
@@ -248,9 +286,9 @@
<v-spacer />
<v-btn
variant="text"
@click="saveFileContent"
@click="showEditorDialog = false"
>
保存
关闭
</v-btn>
</v-toolbar>
@@ -337,6 +375,8 @@ const newFilePath = ref('')
const editingFile = ref<{ path: string; content: string } | null>(null)
const editingFileContent = ref('')
const parentDirectoryForNewItems = ref<string | null>(null) // Track parent context
const selectedSourcePath = ref<string>('') // Track the selected source file or folder
const isAutoFindMode = ref(false) // Track if auto-find mode is enabled
// Tree state
const expandedNodes = ref<string[]>([])
@@ -352,7 +392,7 @@ interface TreeItem {
// Item state
const directories = ref<{ path: string }[]>([])
const files = ref<{ path: string; content: string }[]>([])
const files = ref<{ path: string; content?: string; sourceFilePath?: string }[]>([])
// Computed
const isEditMode = computed(() => !!route.params.id)
@@ -570,7 +610,7 @@ const confirmAddDirectory = () => {
currentContextItem.value = null
}
const confirmAddFile = () => {
const selectAndAddFile = async () => {
if (!newFilePath.value.trim()) return
// Construct the full path if there's a parent directory
@@ -590,20 +630,61 @@ const confirmAddFile = () => {
return
}
const newFile = {
path: fullPath,
content: ''
// Check if we're in auto-find mode and have a selected folder
if (isAutoFindMode.value && selectedSourcePath.value) {
// Auto-find files in the selected folder
const foundFiles = await window.mainApi.invoke('msgFindFilesInFolder', selectedSourcePath.value)
// Add all found files as template files
for (const foundFile of foundFiles) {
// Calculate relative path from selected folder to the found file
const relativePath = foundFile.replace(selectedSourcePath.value, '').substring(1) // Remove leading slash
const fullTargetPath = fullPath ? `${fullPath}/${relativePath}` : relativePath
// Check for duplicates
const duplicate = files.value.some(f => f.path === fullTargetPath)
if (!duplicate) {
const newFile = {
path: fullTargetPath,
sourceFilePath: foundFile
}
files.value.push(newFile)
}
}
// Reset selection state
selectedSourcePath.value = ''
isAutoFindMode.value = false
showFileDialog.value = false
newFilePath.value = ''
parentDirectoryForNewItems.value = null // Clear parent context after creation
currentContextItem.value = null
return
}
// If we have a selected file, just add it
if (selectedSourcePath.value) {
const newFile = {
path: fullPath,
sourceFilePath: selectedSourcePath.value
}
files.value.push(newFile)
files.value.push(newFile)
// Open editor for the new file
editFileContent(newFile)
// Reset selection state
selectedSourcePath.value = ''
isAutoFindMode.value = false
showFileDialog.value = false
newFilePath.value = ''
parentDirectoryForNewItems.value = null // Clear parent context after creation
currentContextItem.value = null
showFileDialog.value = false
newFilePath.value = ''
parentDirectoryForNewItems.value = null // Clear parent context after creation
currentContextItem.value = null
return
}
// Otherwise, show file selection dialog
showSnackbar('请先选择一个文件或文件夹', 'warning')
}
const goBack = () => {
@@ -625,28 +706,8 @@ const collapseAll = () => {
}
const editFile = (item: TreeItem) => {
const file = files.value.find((f) => `file-${f.path}` === item.id)
if (file) {
editFileContent(file)
}
}
const editFileContent = (file: { path: string; content: string }) => {
editingFile.value = file
editingFileContent.value = file.content
showEditorDialog.value = true
}
const saveFileContent = () => {
if (editingFile.value) {
const index = files.value.findIndex(
(f) => f.path === editingFile.value?.path
)
if (index !== -1) {
files.value[index].content = editingFileContent.value
}
}
showEditorDialog.value = false
// For now, just show a message that files are selected, not edited
showSnackbar('该文件是从源文件复制的,无法直接编辑', 'info')
}
const deleteItem = (item: TreeItem) => {
@@ -668,6 +729,23 @@ const showSnackbar = (message: string, color: string = 'error') => {
snackbarVisible.value = true
}
// Methods for file/folder selection
const selectSourceFile = async () => {
const result = await window.mainApi.invoke('msgOpenFile', 'any')
if (!result.canceled && result.filePaths && result.filePaths.length > 0) {
selectedSourcePath.value = result.filePaths[0]
isAutoFindMode.value = false // Not in auto-find mode when selecting a specific file
}
}
const selectSourceFolder = async () => {
const result = await window.mainApi.invoke('msgSelectDirectory')
if (!result.canceled && result.filePath) {
selectedSourcePath.value = result.filePath
isAutoFindMode.value = true // In auto-find mode when selecting a folder
}
}
// Auto focus methods
const autoFocusDirectoryInput = async () => {
await nextTick()