Private
Public Access
1
0

重构:统一文件类型配置管理,移除重复硬编码

新增:
- constants.js 添加 CONFIG 数组(json、xml、yaml、toml、ini、cfg、conf、props、env 等)
- fileTypeHelpers.js 添加 isConfigFile() 函数

优化:
- 移除 6 处重复的文件类型硬编码
- 统一使用 FILE_EXTENSIONS.CONFIG
- 移除 3 处重复的 isOfficeFile() 定义

修改文件:
- web/src/utils/constants.js
- web/src/utils/fileTypeHelpers.js
- web/src/components/FileSystem/composables/useFileEdit.ts
- web/src/components/FileSystem/composables/useFilePreview.ts
- web/src/components/FileSystem/components/ContextMenu.vue
- web/src/composables/useFilePreview.js
This commit is contained in:
2026-02-04 12:37:09 +08:00
parent edd5b7c869
commit ce2698f245
6 changed files with 48 additions and 30 deletions

View File

@@ -47,6 +47,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ContextMenuConfig, FileItem } from '@/types/file-system' import type { ContextMenuConfig, FileItem } from '@/types/file-system'
import { isOfficeFile } from '@/utils/fileTypeHelpers'
// Props // Props
interface Props { interface Props {
@@ -63,15 +64,6 @@ interface Emits {
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
/**
* 判断是否为 Office 文件
*/
const isOfficeFile = (filename: string): boolean => {
if (!filename || typeof filename !== 'string') return false
const ext = filename.split('.').pop()?.toLowerCase()
return ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes(ext || '')
}
/** /**
* 处理菜单项点击 * 处理菜单项点击
*/ */

View File

@@ -116,7 +116,7 @@ export function useFileEdit(options: UseFileEditOptions = {}) {
// 文本或代码文件(可编辑) // 文本或代码文件(可编辑)
const isTextFile = FILE_EXTENSIONS.TEXT.includes(ext) || const isTextFile = FILE_EXTENSIONS.TEXT.includes(ext) ||
FILE_EXTENSIONS.CODE.includes(ext) || FILE_EXTENSIONS.CODE.includes(ext) ||
['json', 'xml', 'yaml', 'yml', 'toml', 'ini', 'conf', 'cfg', 'props'].includes(ext) FILE_EXTENSIONS.CONFIG.includes(ext)
// 如果是媒体文件或文本文件,就不是二进制 // 如果是媒体文件或文本文件,就不是二进制
if (isMediaFile || isTextFile) return false if (isMediaFile || isTextFile) return false

View File

@@ -118,6 +118,11 @@ export function useFilePreview(options: UseFilePreviewOptions = {}) {
return 'Code' as FileType return 'Code' as FileType
} }
// 配置文件(返回 Code 类型,因为它们也是可编辑的文本格式)
if (FILE_EXTENSIONS.CONFIG.includes(ext)) {
return 'Code' as FileType
}
// 文本 // 文本
if (FILE_EXTENSIONS.TEXT.includes(ext)) { if (FILE_EXTENSIONS.TEXT.includes(ext)) {
return 'Text' as FileType return 'Text' as FileType
@@ -227,7 +232,8 @@ export function useFilePreview(options: UseFilePreviewOptions = {}) {
const ext = filename.split('.').pop()?.toLowerCase() || '' const ext = filename.split('.').pop()?.toLowerCase() || ''
return FILE_EXTENSIONS.CODE.includes(ext) || return FILE_EXTENSIONS.CODE.includes(ext) ||
FILE_EXTENSIONS.TEXT.includes(ext) || FILE_EXTENSIONS.TEXT.includes(ext) ||
['html', 'htm', 'md', 'markdown', 'json', 'xml'].includes(ext) FILE_EXTENSIONS.CONFIG.includes(ext) ||
['html', 'htm', 'md', 'markdown'].includes(ext)
} }
/** /**

View File

@@ -9,6 +9,7 @@ import { ref, computed } from 'vue'
import { marked } from '@/utils/markedExtensions' import { marked } from '@/utils/markedExtensions'
import { FILE_EXTENSIONS, FILE_SIZE_THRESHOLDS } from '@/utils/constants' import { FILE_EXTENSIONS, FILE_SIZE_THRESHOLDS } from '@/utils/constants'
import { getExt } from '@/utils/fileHelpers' import { getExt } from '@/utils/fileHelpers'
import { isOfficeFile } from '@/utils/fileTypeHelpers'
import { debugLog, debugWarn, debugError } from '@/utils/debugLog' import { debugLog, debugWarn, debugError } from '@/utils/debugLog'
/** /**
@@ -532,16 +533,6 @@ export function useFilePreview(options = {}) {
imageHeight.value = 0 imageHeight.value = 0
} }
/**
* 判断是否为 Office 文件
* @param {string} fileName - 文件名
* @returns {boolean}
*/
const isOfficeFile = (fileName) => {
const ext = getExt(fileName).toLowerCase()
return ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes(ext)
}
return { return {
// 状态 // 状态
previewUrl, previewUrl,

View File

@@ -73,11 +73,23 @@ export const FILE_EXTENSIONS = {
CODE: [ CODE: [
'js', 'ts', 'jsx', 'tsx', 'cts', 'mts', 'cjs', 'mjs', 'js', 'ts', 'jsx', 'tsx', 'cts', 'mts', 'cjs', 'mjs',
'vue', 'py', 'java', 'c', 'cpp', 'h', 'go', 'rs', 'php', 'rb', 'cs', 'swift', 'kt', 'vue', 'py', 'java', 'c', 'cpp', 'h', 'go', 'rs', 'php', 'rb', 'cs', 'swift', 'kt',
'scala', 'css', 'scss', 'sass', 'less', 'json', 'xml', 'yaml', 'yml', 'sql', 'sh', 'bat', 'ps1', 'scala', 'css', 'scss', 'sass', 'less', 'sql', 'sh', 'bat', 'ps1',
'flow', 'props', 'pch', 'cc', 'cxx', 'hpp', 'hxx', 'tcc', 'defs', 'makefile', 'mk', 'cmake', 'flow', 'pch', 'cc', 'cxx', 'hpp', 'hxx', 'tcc', 'defs', 'makefile', 'mk', 'cmake',
'tex', 'm', 'r', 'matlab', 'latex', 'rst', 'adoc' 'tex', 'm', 'r', 'matlab', 'latex', 'rst', 'adoc'
], ],
// 配置文件(可编辑的文本格式)
CONFIG: [
// 数据格式
'json', 'xml', 'yaml', 'yml',
// 配置文件
'toml', 'ini', 'cfg', 'conf',
// 环境变量/属性
'props', 'env', 'dotenv',
// 其他
'manifest', 'lock', 'ignore'
],
// 纯文本文件 // 纯文本文件
TEXT: ['txt', 'text', 'log', 'md', 'markdown', 'rst', 'adoc', 'tex', 'msg', 'csv', 'tsv'], TEXT: ['txt', 'text', 'log', 'md', 'markdown', 'rst', 'adoc', 'tex', 'msg', 'csv', 'tsv'],
@@ -193,6 +205,17 @@ const initIconMap = () => {
// 代码文件(通用) // 代码文件(通用)
FILE_EXTENSIONS.CODE.forEach(ext => FILE_ICON_MAP.set(ext, FILE_ICONS.CODE)) FILE_EXTENSIONS.CODE.forEach(ext => FILE_ICON_MAP.set(ext, FILE_ICONS.CODE))
// 配置文件(使用特定图标)
const configIcons = {
'json': FILE_ICONS.JSON,
'xml': FILE_ICONS.XML,
'yaml': FILE_ICONS.YAML,
'yml': FILE_ICONS.YAML
}
FILE_EXTENSIONS.CONFIG.forEach(ext => {
FILE_ICON_MAP.set(ext, configIcons[ext] || FILE_ICONS.YAML)
})
// 编程语言特定图标 // 编程语言特定图标
const langIcons = { const langIcons = {
// Java // Java
@@ -219,11 +242,6 @@ const initIconMap = () => {
'scss': FILE_ICONS.CSS, 'scss': FILE_ICONS.CSS,
'sass': FILE_ICONS.CSS, 'sass': FILE_ICONS.CSS,
'less': FILE_ICONS.CSS, 'less': FILE_ICONS.CSS,
// Data
'json': FILE_ICONS.JSON,
'xml': FILE_ICONS.XML,
'yaml': FILE_ICONS.YAML,
'yml': FILE_ICONS.YAML,
// Shell // Shell
'sh': FILE_ICONS.SHELL, 'sh': FILE_ICONS.SHELL,
'bash': FILE_ICONS.SHELL, 'bash': FILE_ICONS.SHELL,

View File

@@ -35,12 +35,13 @@ export const KNOWN_BINARY_TYPES = [
] ]
/** /**
* 文本可编辑类型 * 文本可编辑类型(包括代码、配置和文本文件)
* @type {string[]} * @type {string[]}
*/ */
export const TEXT_EDITABLE_TYPES = [ export const TEXT_EDITABLE_TYPES = [
...FILE_EXTENSIONS.CODE, ...FILE_EXTENSIONS.CODE,
'md', 'markdown', 'txt', 'json', 'xml', 'yaml', 'yml', 'toml', 'ini', 'cfg', 'conf' ...FILE_EXTENSIONS.CONFIG,
...FILE_EXTENSIONS.TEXT
] ]
/** /**
@@ -133,6 +134,16 @@ export const isTextEditable = (path) => {
return TEXT_EDITABLE_TYPES.includes(ext) return TEXT_EDITABLE_TYPES.includes(ext)
} }
/**
* 判断是否为配置文件
* @param {string} path - 文件路径
* @returns {boolean}
*/
export const isConfigFile = (path) => {
const ext = getExt(path)
return FILE_EXTENSIONS.CONFIG.includes(ext)
}
/** /**
* 获取文件类型分类 * 获取文件类型分类
* @param {string} path - 文件路径 * @param {string} path - 文件路径