refactor(types): 将类型定义移动到独立的types模块

将原本分散在多个文件中的TreeNode和Template类型定义集中到src/types模块中,并更新所有相关引用
修改tsconfig配置以包含新的types目录
优化IPCs中模板处理逻辑,改进文件复制和路径处理
This commit is contained in:
zhanggy committed 2025-10-31 17:20:09 +08:00
1 parent 35a0821153
commit e496aa59f4
10 files changed
+49 -44

No files matched your search

+20 -11
View File
@@ -6,9 +6,11 @@ import {
readFileSync,
existsSync,
ensureDirSync,
copyFileSync
copyFileSync,
readdirSync
} from 'fs-extra'
import { autoUpdater } from 'electron-updater'
import { Template, TreeNode } from '../types'
/*
* IPC Communications
@@ -182,7 +184,7 @@ export default class IPCs {
const userDataPath = join(Constants.APP_DATA_PATH, 'data')
const filePath = join(userDataPath, 'templates.json')
let templates = []
let templates: Template[] = []
if (existsSync(filePath)) {
const templatesData = readFileSync(filePath, 'utf-8')
templates = JSON.parse(templatesData)
@@ -203,11 +205,14 @@ export default class IPCs {
ensureDirSync(baseDirPath)
// Helper function to traverse the tree and collect all nodes
const collectAllNodes = (nodes, allNodes = []) => {
const collectAllNodes = (nodes: TreeNode[], allNodes: TreeNode[] = [], parent?: TreeNode) => {
for (const node of nodes) {
allNodes.push(node);
allNodes.push({
...node,
path: join(parent?.path || '', node.path)
});
if (node.children) {
collectAllNodes(node.children, allNodes);
collectAllNodes(node.children, allNodes, node);
}
}
return allNodes;
@@ -227,13 +232,17 @@ export default class IPCs {
const fileDir = dirname(nodePath);
ensureDirSync(fileDir);
if (node.sourceFilePath) {
// Copy from source file
const sourceContent = readFileSync(node.sourceFilePath);
writeFileSync(nodePath, sourceContent);
} else if (node.content) {
if (node.sourceType === 'file') {
copyFileSync(node.sourcePath, nodePath);
} else {
// Write content directly
writeFileSync(nodePath, node.content, 'utf-8');
const files = readdirSync(node.sourcePath, { withFileTypes: true })
for (const file of files) {
if (file.isFile() && file.name.startsWith(baseDirName)) {
const filePath = join(node.sourcePath, file.name);
copyFileSync(filePath, nodePath);
}
}
}
}
}
+1 -1
View File
@@ -39,7 +39,7 @@
<script setup lang="ts">
import { ref, watch, nextTick } from 'vue'
import { TreeNode } from '@/renderer/store/template'
import { TreeNode } from '@/types'
interface Props {
modelValue: boolean
+2 -8
View File
@@ -26,7 +26,6 @@
label="选择文件"
placeholder="点击输入框选择文件"
readonly
:rules="[fileSelectionRule]"
:append-inner-icon="'mdi-file'"
density="comfortable"
class="mt-4"
@@ -39,7 +38,6 @@
label="选择文件夹"
placeholder="点击输入框选择文件夹"
readonly
:rules="[fileSelectionRule]"
:append-inner-icon="'mdi-folder'"
density="comfortable"
class="mt-4"
@@ -81,7 +79,7 @@
<script setup lang="ts">
import { ref, watch, nextTick } from 'vue'
import { TreeNode } from '@/renderer/store/template'
import { TreeNode } from '@/types'
interface Props {
modelValue: boolean
@@ -135,11 +133,7 @@ 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 () => {
+1 -1
View File
@@ -59,7 +59,7 @@
<script setup lang="ts">
import { computed } from 'vue'
import { Template, TreeNode } from '@/renderer/store/template'
import { Template, TreeNode } from '@/types'
interface Props {
template: Template
@@ -146,7 +146,8 @@
</template>
<script setup lang="ts">
import { useTemplateStore, TreeNode } from '@/renderer/store/template'
import { useTemplateStore } from '@/renderer/store/template'
import { TreeNode } from '@/types'
import { useSnackbarStore } from '@/renderer/store/snackbar'
import TemplateTree from '@/renderer/components/TemplateTree.vue'
import DirectoryDialog from '@/renderer/components/DirectoryDialog.vue'
+2 -2
View File
@@ -89,8 +89,8 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useTemplateStore, TreeNode } from '@/renderer/store/template'
import { Template } from '@/renderer/store/template'
import { useTemplateStore } from '@/renderer/store/template'
import { TreeNode, Template } from '@/types'
import TemplateTree from '@/renderer/components/TemplateTree.vue'
import TemplateCard from '@/renderer/components/TemplateCard.vue'
import { ConfirmDialogService } from '@/renderer/utils/confirm-dialog-service'
+1 -19
View File
@@ -1,24 +1,6 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
// 定义树状结构的节点
export interface TreeNode {
id: string
name: string
path: string // 完整路径
type: 'directory' | 'file'
children?: TreeNode[]
sourcePath?: string
sourceType?: 'file' | 'folder' // 记录选择的是文件还是文件夹
}
export interface Template {
id: string
name: string
description: string
// 使用树状结构存储
treeStructure: TreeNode[]
}
import { TreeNode, Template } from '@/types'
export const useTemplateStore = defineStore('template', () => {
const templates = ref<Template[]>([])
+18
View File
@@ -0,0 +1,18 @@
// 定义树状结构的节点
export interface TreeNode {
id: string
name: string
path: string // 完整路径
type: 'directory' | 'file'
children?: TreeNode[]
sourcePath?: string
sourceType?: 'file' | 'folder' // 记录选择的是文件还是文件夹
}
export interface Template {
id: string
name: string
description: string
// 使用树状结构存储
treeStructure: TreeNode[]
}
+1 -1
View File
@@ -19,7 +19,7 @@
},
"lib": ["esnext", "dom"]
},
"include": ["src/*.ts", "src/*.d.ts", "src/renderer", "src/renderer/auto-imports.d.ts"],
"include": ["src/*.ts", "src/*.d.ts", "src/renderer", "src/renderer/auto-imports.d.ts", "src/types"],
"references": [
{
"path": "./tsconfig.node.json"
+1
View File
@@ -12,6 +12,7 @@
"include": [
"src/main",
"src/preload",
"src/types",
"package.json",
"eslint.config.ts",
"vite.config.mts",