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">
import type { ContextMenuConfig, FileItem } from '@/types/file-system'
import { isOfficeFile } from '@/utils/fileTypeHelpers'
// Props
interface Props {
@@ -63,15 +64,6 @@ interface 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) ||
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

View File

@@ -118,6 +118,11 @@ export function useFilePreview(options: UseFilePreviewOptions = {}) {
return 'Code' as FileType
}
// 配置文件(返回 Code 类型,因为它们也是可编辑的文本格式)
if (FILE_EXTENSIONS.CONFIG.includes(ext)) {
return 'Code' as FileType
}
// 文本
if (FILE_EXTENSIONS.TEXT.includes(ext)) {
return 'Text' as FileType
@@ -227,7 +232,8 @@ export function useFilePreview(options: UseFilePreviewOptions = {}) {
const ext = filename.split('.').pop()?.toLowerCase() || ''
return FILE_EXTENSIONS.CODE.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 { FILE_EXTENSIONS, FILE_SIZE_THRESHOLDS } from '@/utils/constants'
import { getExt } from '@/utils/fileHelpers'
import { isOfficeFile } from '@/utils/fileTypeHelpers'
import { debugLog, debugWarn, debugError } from '@/utils/debugLog'
/**
@@ -532,16 +533,6 @@ export function useFilePreview(options = {}) {
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 {
// 状态
previewUrl,

View File

@@ -73,11 +73,23 @@ export const FILE_EXTENSIONS = {
CODE: [
'js', 'ts', 'jsx', 'tsx', 'cts', 'mts', 'cjs', 'mjs',
'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',
'flow', 'props', 'pch', 'cc', 'cxx', 'hpp', 'hxx', 'tcc', 'defs', 'makefile', 'mk', 'cmake',
'scala', 'css', 'scss', 'sass', 'less', 'sql', 'sh', 'bat', 'ps1',
'flow', 'pch', 'cc', 'cxx', 'hpp', 'hxx', 'tcc', 'defs', 'makefile', 'mk', 'cmake',
'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'],
@@ -193,6 +205,17 @@ const initIconMap = () => {
// 代码文件(通用)
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 = {
// Java
@@ -219,11 +242,6 @@ const initIconMap = () => {
'scss': FILE_ICONS.CSS,
'sass': 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
'sh': FILE_ICONS.SHELL,
'bash': FILE_ICONS.SHELL,

View File

@@ -35,12 +35,13 @@ export const KNOWN_BINARY_TYPES = [
]
/**
* 文本可编辑类型
* 文本可编辑类型(包括代码、配置和文本文件)
* @type {string[]}
*/
export const TEXT_EDITABLE_TYPES = [
...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)
}
/**
* 判断是否为配置文件
* @param {string} path - 文件路径
* @returns {boolean}
*/
export const isConfigFile = (path) => {
const ext = getExt(path)
return FILE_EXTENSIONS.CONFIG.includes(ext)
}
/**
* 获取文件类型分类
* @param {string} path - 文件路径