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, readFileSync,
existsSync, existsSync,
ensureDirSync, ensureDirSync,
copyFileSync copyFileSync,
readdirSync
} from 'fs-extra' } from 'fs-extra'
import { autoUpdater } from 'electron-updater' import { autoUpdater } from 'electron-updater'
import { Template, TreeNode } from '../types'
/* /*
* IPC Communications * IPC Communications
@@ -182,7 +184,7 @@ export default class IPCs {
const userDataPath = join(Constants.APP_DATA_PATH, 'data') const userDataPath = join(Constants.APP_DATA_PATH, 'data')
const filePath = join(userDataPath, 'templates.json') const filePath = join(userDataPath, 'templates.json')
let templates = [] let templates: Template[] = []
if (existsSync(filePath)) { if (existsSync(filePath)) {
const templatesData = readFileSync(filePath, 'utf-8') const templatesData = readFileSync(filePath, 'utf-8')
templates = JSON.parse(templatesData) templates = JSON.parse(templatesData)
@@ -203,11 +205,14 @@ export default class IPCs {
ensureDirSync(baseDirPath) ensureDirSync(baseDirPath)
// Helper function to traverse the tree and collect all nodes // 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) { for (const node of nodes) {
allNodes.push(node); allNodes.push({
...node,
path: join(parent?.path || '', node.path)
});
if (node.children) { if (node.children) {
collectAllNodes(node.children, allNodes); collectAllNodes(node.children, allNodes, node);
} }
} }
return allNodes; return allNodes;
@@ -227,13 +232,17 @@ export default class IPCs {
const fileDir = dirname(nodePath); const fileDir = dirname(nodePath);
ensureDirSync(fileDir); ensureDirSync(fileDir);
if (node.sourceFilePath) { if (node.sourceType === 'file') {
// Copy from source file copyFileSync(node.sourcePath, nodePath);
const sourceContent = readFileSync(node.sourceFilePath); } else {
writeFileSync(nodePath, sourceContent);
} else if (node.content) {
// Write content directly // 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"> <script setup lang="ts">
import { ref, watch, nextTick } from 'vue' import { ref, watch, nextTick } from 'vue'
import { TreeNode } from '@/renderer/store/template' import { TreeNode } from '@/types'
interface Props { interface Props {
modelValue: boolean modelValue: boolean
+2 -8
View File
@@ -26,7 +26,6 @@
label="选择文件" label="选择文件"
placeholder="点击输入框选择文件" placeholder="点击输入框选择文件"
readonly readonly
:rules="[fileSelectionRule]"
:append-inner-icon="'mdi-file'" :append-inner-icon="'mdi-file'"
density="comfortable" density="comfortable"
class="mt-4" class="mt-4"
@@ -39,7 +38,6 @@
label="选择文件夹" label="选择文件夹"
placeholder="点击输入框选择文件夹" placeholder="点击输入框选择文件夹"
readonly readonly
:rules="[fileSelectionRule]"
:append-inner-icon="'mdi-folder'" :append-inner-icon="'mdi-folder'"
density="comfortable" density="comfortable"
class="mt-4" class="mt-4"
@@ -81,7 +79,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, nextTick } from 'vue' import { ref, watch, nextTick } from 'vue'
import { TreeNode } from '@/renderer/store/template' import { TreeNode } from '@/types'
interface Props { interface Props {
modelValue: boolean modelValue: boolean
@@ -135,11 +133,7 @@ watch(isVisible, (newValue) => {
const requiredRule = (fieldName: string) => (v: string | null | undefined) => const requiredRule = (fieldName: string) => (v: string | null | undefined) =>
!!v || `${fieldName}为必填项` !!v || `${fieldName}为必填项`
// File selection validation rule
const fileSelectionRule = () => {
if (isEditMode.value) return true // 编辑模式下不需要验证
return !!selectedFilePath.value || !!selectedFolderPath.value || '请选择文件或文件夹'
}
// Methods // Methods
const autoFocusInput = async () => { const autoFocusInput = async () => {
+1 -1
View File
@@ -59,7 +59,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed } from 'vue'
import { Template, TreeNode } from '@/renderer/store/template' import { Template, TreeNode } from '@/types'
interface Props { interface Props {
template: Template template: Template
@@ -146,7 +146,8 @@
</template> </template>
<script setup lang="ts"> <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 { useSnackbarStore } from '@/renderer/store/snackbar'
import TemplateTree from '@/renderer/components/TemplateTree.vue' import TemplateTree from '@/renderer/components/TemplateTree.vue'
import DirectoryDialog from '@/renderer/components/DirectoryDialog.vue' import DirectoryDialog from '@/renderer/components/DirectoryDialog.vue'
+2 -2
View File
@@ -89,8 +89,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, onMounted } from 'vue' import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useTemplateStore, TreeNode } from '@/renderer/store/template' import { useTemplateStore } from '@/renderer/store/template'
import { Template } from '@/renderer/store/template' import { TreeNode, Template } from '@/types'
import TemplateTree from '@/renderer/components/TemplateTree.vue' import TemplateTree from '@/renderer/components/TemplateTree.vue'
import TemplateCard from '@/renderer/components/TemplateCard.vue' import TemplateCard from '@/renderer/components/TemplateCard.vue'
import { ConfirmDialogService } from '@/renderer/utils/confirm-dialog-service' import { ConfirmDialogService } from '@/renderer/utils/confirm-dialog-service'
+1 -19
View File
@@ -1,24 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref } from 'vue' import { ref } from 'vue'
import { TreeNode, Template } from '@/types'
// 定义树状结构的节点
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[]
}
export const useTemplateStore = defineStore('template', () => { export const useTemplateStore = defineStore('template', () => {
const templates = ref<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"] "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": [ "references": [
{ {
"path": "./tsconfig.node.json" "path": "./tsconfig.node.json"
+1
View File
@@ -12,6 +12,7 @@
"include": [ "include": [
"src/main", "src/main",
"src/preload", "src/preload",
"src/types",
"package.json", "package.json",
"eslint.config.ts", "eslint.config.ts",
"vite.config.mts", "vite.config.mts",