diff --git a/src/main/IPCs.ts b/src/main/IPCs.ts
index 7cc84c3..70f8fa4 100644
--- a/src/main/IPCs.ts
+++ b/src/main/IPCs.ts
@@ -75,7 +75,7 @@ export default class IPCs {
const filePath = dialogResult.filePaths[0];
const fs = require('fs');
const isDirectory = fs.statSync(filePath).isDirectory();
-
+
return {
canceled: false,
filePath: filePath,
@@ -86,7 +86,7 @@ export default class IPCs {
return { canceled: true }
})
-
+
// Find all files in a folder recursively
ipcMain.handle(
diff --git a/src/renderer/components/FileDialog.vue b/src/renderer/components/FileDialog.vue
index 2add1f5..f5d4696 100644
--- a/src/renderer/components/FileDialog.vue
+++ b/src/renderer/components/FileDialog.vue
@@ -20,17 +20,30 @@
ref="inputRef"
/>
-
+
+
+
+
@@ -44,6 +57,9 @@
选择文件夹则会自动匹配该文件夹下的文件进行复制并且重命名
+
+ 文件和文件夹选择其中一个即可
+
@@ -54,7 +70,7 @@
{{ isEditMode ? '保存' : '添加' }}
@@ -76,7 +92,7 @@ interface Props {
interface Emits {
(e: 'update:modelValue', value: boolean): void
- (e: 'confirm', data: { path: string; sourceFilePath?: string }): void
+ (e: 'confirm', data: { path: string; sourcePath?: string; sourceType?: 'file' | 'folder' }): void
}
const props = withDefaults(defineProps(), {
@@ -91,7 +107,8 @@ const emit = defineEmits()
const isVisible = ref(false)
const formValid = ref(false)
const filePath = ref('')
-const selectedSourcePath = ref('')
+const selectedFilePath = ref('')
+const selectedFolderPath = ref('')
const inputRef = ref(null)
// Computed
@@ -103,7 +120,8 @@ watch(() => props.modelValue, (newValue) => {
if (newValue) {
// Reset form when dialog opens
filePath.value = props.editingItem?.path || ''
- selectedSourcePath.value = props.editingItem?.sourceFilePath || ''
+ selectedFilePath.value = props.editingItem?.sourceType === 'file' ? props.editingItem?.sourcePath || '' : ''
+ selectedFolderPath.value = props.editingItem?.sourceType === 'folder' ? props.editingItem?.sourcePath || '' : ''
autoFocusInput()
}
})
@@ -117,6 +135,12 @@ watch(isVisible, (newValue) => {
const requiredRule = (fieldName: string) => (v: string | null | undefined) =>
!!v || `${fieldName}为必填项`
+// File selection validation rule
+const fileSelectionRule = () => {
+ if (isEditMode.value) return true // 编辑模式下不需要验证
+ return !!selectedFilePath.value || !!selectedFolderPath.value || '请选择文件或文件夹'
+}
+
// Methods
const autoFocusInput = async () => {
await nextTick()
@@ -125,22 +149,45 @@ const autoFocusInput = async () => {
}
}
-const selectSourceFileOrFolder = async () => {
- // 使用现有的主进程API来选择文件或文件夹
- const result = await window.mainApi.invoke('msgSelectFileOrFolder')
+const selectSourceFile = async () => {
+ // 使用主进程API来选择文件
+ const result = await window.mainApi.invoke('msgOpenFile', 'any')
- if (result && result.filePath) {
- selectedSourcePath.value = result.filePath
+ if (result && !result.canceled && result.filePaths.length > 0) {
+ selectedFilePath.value = result.filePaths[0]
+ selectedFolderPath.value = '' // 清空文件夹选择
+ }
+}
+
+const selectSourceFolder = async () => {
+ // 使用主进程API来选择文件夹
+ const result = await window.mainApi.invoke('msgSelectDirectory')
+
+ if (result && !result.canceled && result.filePath) {
+ selectedFolderPath.value = result.filePath
+ selectedFilePath.value = '' // 清空文件选择
}
}
const confirm = () => {
if (!filePath.value.trim()) return
+ // 确定选择的源类型和路径
+ let sourcePathValue: string | undefined
+ let sourceType: 'file' | 'folder' | undefined
+
+ if (selectedFilePath.value) {
+ sourcePathValue = selectedFilePath.value
+ sourceType = 'file'
+ } else if (selectedFolderPath.value) {
+ sourcePathValue = selectedFolderPath.value
+ sourceType = 'folder'
+ }
emit('confirm', {
path: filePath.value,
- sourceFilePath: selectedSourcePath.value || undefined
+ sourcePath: sourcePathValue,
+ sourceType
})
close()
@@ -148,7 +195,8 @@ const confirm = () => {
const reset = () => {
filePath.value = ''
- selectedSourcePath.value = ''
+ selectedFilePath.value = ''
+ selectedFolderPath.value = ''
formValid.value = false
}
diff --git a/src/renderer/screens/CreateTemplateScreen.vue b/src/renderer/screens/CreateTemplateScreen.vue
index 5b607ad..e2569b3 100644
--- a/src/renderer/screens/CreateTemplateScreen.vue
+++ b/src/renderer/screens/CreateTemplateScreen.vue
@@ -284,13 +284,11 @@ const handleDirectoryDialogConfirm = (data: { path: string }) => {
path: path,
type: 'directory'
}
- console.log('updatedNode', updatedNode)
treeStructure.value = updateNodeInTree(
treeStructure.value,
- currentEditingItem.value.path,
+ currentEditingItem.value.id,
updatedNode
)
- console.log('update treeStructure', treeStructure.value)
} else {
// Create new directory node
const newNode: TreeNode = {
@@ -360,8 +358,8 @@ const updateNodeInTree = (
-const handleFileDialogConfirm = (data: { path: string; sourceFilePath?: string }) => {
- const { path, sourceFilePath } = data
+const handleFileDialogConfirm = (data: { path: string; sourcePath?: string; sourceType?: 'file' | 'folder' }) => {
+ const { path, sourcePath, sourceType } = data
const newId = generateUniqueId('file')
@@ -373,7 +371,8 @@ const handleFileDialogConfirm = (data: { path: string; sourceFilePath?: string }
name: path,
path: path,
type: 'file',
- sourceFilePath: sourceFilePath
+ sourcePath: sourcePath,
+ sourceType
}
treeStructure.value = updateNodeInTree(
treeStructure.value,
@@ -410,7 +409,8 @@ const handleFileDialogConfirm = (data: { path: string; sourceFilePath?: string }
name: path,
path: path,
type: 'file',
- sourceFilePath
+ sourcePath,
+ sourceType
}
// Add to tree structure
diff --git a/src/renderer/store/template.ts b/src/renderer/store/template.ts
index d130355..35c2ff3 100644
--- a/src/renderer/store/template.ts
+++ b/src/renderer/store/template.ts
@@ -8,7 +8,8 @@ export interface TreeNode {
path: string // 完整路径
type: 'directory' | 'file'
children?: TreeNode[]
- sourceFilePath?: string
+ sourcePath?: string
+ sourceType?: 'file' | 'folder' // 记录选择的是文件还是文件夹
}
export interface Template {