Private
Public Access
1
0

重构:文件系统模块化架构,增强 Markdown 渲染

- 拆分 FileSystem.vue 为模块化组件架构
- 新增 Markdown Mermaid 图表渲染支持
- 新增 180+ 编程语言代码高亮
- 修复编辑/预览模式切换渲染问题
- 优化亮色/暗色模式主题适配
- 新增 TypeScript 类型定义
This commit is contained in:
2026-02-04 03:31:22 +08:00
parent eb2cbad17b
commit a5d30684ed
119 changed files with 11244 additions and 12042 deletions

View File

@@ -0,0 +1,317 @@
# 代码审查报告
**日期**: 2025-01-30
**审查范围**: 前端 Vue 组件、后端 Go 代码
---
## 一、关键问题总结
### 🔴 严重问题(必须修复)
#### 1. **FileSystem.vue 文件过大 - 4266 行**
- **问题**: 单文件组件过大,违反单一职责原则
- **影响**: 难以维护、测试困难、代码复用性差
- **建议**: 拆分为多个小组件和 composables
#### 2. **重复的扩展名获取逻辑**
- **位置**: `FileSystem.vue:3129-3171` vs `fileHelpers.js:8-14`
- **问题**: `currentFileExtension` 重复实现了 `getExt` 的功能
- **建议**: 统一使用 `getExt` 函数
#### 3. **调试日志过多 - 58 个**
- **位置**: `FileSystem.vue`
- **问题**: 过度防御性编程,大量 `debugLog``console.log`
- **影响**: 性能影响、代码可读性差
- **建议**: 移除或使用环境变量控制
### 🟡 中等问题(建议优化)
#### 4. **重复计算属性**
```javascript
// FileSystem.vue:3202 - 完全重复
const isEditableFile = computed(() => isEditableView.value)
```
**建议**: 删除,直接使用 `isEditableView`
#### 5. **相似计算属性可合并**
```javascript
// FileSystem.vue:3205-3217
const canSaveFile = computed(() => {
return isEditableView.value &&
fileContent.value !== '' &&
originalContent.value !== fileContent.value
})
const canResetContent = computed(() => {
return isEditableView.value &&
fileContent.value !== '' &&
originalContent.value !== undefined &&
originalContent.value !== fileContent.value
})
```
**建议**: 提取共享逻辑
```javascript
const contentChanged = computed(() =>
fileContent.value !== '' &&
originalContent.value !== fileContent.value
)
const canSaveFile = computed(() => isEditableView.value && contentChanged.value)
const canResetContent = computed(() =>
isEditableView.value && contentChanged.value && originalContent.value !== undefined
)
```
#### 6. **currentFileExtension 逻辑嵌套**
```javascript
// FileSystem.vue:3129-3171
const currentFileExtension = computed(() => {
let path = ''
if (selectedFilePath.value) {
path = selectedFilePath.value
} else if (filePath.value) {
path = filePath.value
}
// ... 更多嵌套逻辑
})
```
**建议**: 简化为线性流程
```javascript
const currentFileExtension = computed(() => {
const path = selectedFilePath.value || filePath.value
if (!path) return ''
// 特殊文件名映射
const fileName = path.split(/[/\\]/).pop()?.toLowerCase() || ''
const specialMapping = {/* ... */}
if (specialMapping[fileName]) return specialMapping[fileName]
// 普通扩展名
return getExt(path)
})
```
#### 7. **CodeEditor.vue 语言包导入冗余**
```javascript
// CodeEditor.vue:43-88 - 46 行的语言映射
const LANGUAGE_MAP = {
javascript: ['js', 'jsx', 'mjs', 'cjs'],
typescript: ['ts', 'tsx'],
// ... 30+ 个映射
}
```
**问题**: 与 `constants.js` 中的 `FILE_EXTENSIONS` 重复
**建议**: 复用 `constants.js` 的定义
---
## 二、前端代码质量分析
### 文件大小统计
| 文件 | 行数 | 评级 |
|------|------|------|
| FileSystem.vue | 4266 | 🔴 过大 |
| CodeEditor.vue | 334 | 🟢 合理 |
| constants.js | 318 | 🟢 合理 |
| fileHelpers.js | 41 | 🟢 合理 |
### 代码规范问题
#### 命名规范
**好的例子**:
- `getExt()` - 清晰简洁
- `currentFileExtension` - 语义明确
⚠️ **需改进**:
- `imageWidth`/`imageHeight` vs `imageSize` (已删除) - 命名不一致
#### 函数复杂度
🔴 **高复杂度函数**:
1. `readFile()` - 200+ 行,嵌套深度 5+
2. `previewHtml()` - 150+ 行
3. `extractHtmlStyles()` - 100+ 行
#### DRY 原则违反
1. **扩展名获取**: `currentFileExtension` vs `getExt()`
2. **路径分隔符处理**: 多处重复 `/[/\\]/` 正则
3. **文件类型检查**: `isHtmlFile` vs `isHtml()` 函数重复
---
## 三、后端代码质量分析
### Go 代码检查
#### config.go
**好的方面**:
- 清晰的配置结构
- 良好的默认值处理
- 安全的路径验证
⚠️ **需改进**:
```go
// config.go:256-289 - getAllowedExtensions
func getAllowedExtensions() map[string]bool {
return map[string]bool{
".jpg": true,
// 30+ 个硬编码扩展名
}
}
```
**建议**: 考虑从配置文件加载,或使用更紧凑的表示方式
#### asset_handler.go
**好的方面**:
- 良好的安全检查(路径遍历防护)
- 清晰的错误处理
⚠️ **需改进**:
```go
// asset_handler.go:66-165 - handleLocalFileRequest 函数过长
// 建议拆分为多个小函数
```
---
## 四、具体优化建议
### 优先级 1: 立即修复
#### 1. 移除 FileSystem.vue 中的调试代码
```javascript
// 删除所有 debugLog 调用58 个)
// 或使用环境变量控制
const DEBUG = import.meta.env.DEV
const debugLog = DEBUG ? console.log : () => {}
```
#### 2. 删除重复计算属性
```javascript
// 删除 FileSystem.vue:3202
- const isEditableFile = computed(() => isEditableView.value)
```
#### 3. 统一使用 getExt
```javascript
// FileSystem.vue:3129-3171
// 简化 currentFileExtension复用 getExt
```
### 优先级 2: 短期优化
#### 4. 提取 Composables
```javascript
// 创建 src/composables/useFileExtension.js
export function useFileExtension() {
const getExtension = (path) => {
// 统一的扩展名获取逻辑
}
const isSpecialFile = (fileName) => {
// 特殊文件名判断
}
return { getExtension, isSpecialFile }
}
```
#### 5. 拆分 FileSystem.vue
```
components/FileSystem/
├── index.vue (主组件,< 500 行)
├── useFileOperations.js (文件操作)
├── useFilePreview.js (预览逻辑)
├── useFileEdit.js (编辑逻辑)
└── usePathNavigation.js (路径导航)
```
#### 6. 合并相似计算属性
```javascript
// 提取共享逻辑
const contentChanged = computed(() =>
fileContent.value !== '' &&
originalContent.value !== fileContent.value
)
```
### 优先级 3: 长期重构
#### 7. 统一文件类型定义
```javascript
// 将 LANGUAGE_MAP 迁移到 constants.js
// 与 FILE_EXTENSIONS 合并
export const FILE_CATEGORIES = {
CODE: { extensions: ['js', 'ts', /* ... */ }, syntaxHighlight: javascript },
MARKUP: { extensions: ['html', 'css', /* ... */ ], syntaxHighlight: html },
// ...
}
```
#### 8. 类型安全
```typescript
// 添加 TypeScript 类型定义
interface FileExtension {
name: string
category: FileCategory
syntaxHighlight?: Language
}
```
---
## 五、代码质量指标
### 当前状态
| 指标 | 当前值 | 目标值 | 评级 |
|------|--------|--------|------|
| 单文件最大行数 | 4266 | < 500 | 🔴 |
| 函数平均行数 | ~50 | < 30 | 🟡 |
| 代码重复率 | ~5% | < 3% | 🟡 |
| 调试语句数量 | 58 | 0 (生产) | 🔴 |
| 圈复杂度 | 15+ | < 10 | 🟡 |
---
## 六、检查清单
### 前端代码
- [ ] 移除所有调试日志
- [ ] 删除重复计算属性
- [ ] 简化 currentFileExtension
- [ ] 提取 composables
- [ ] 拆分 FileSystem.vue
- [ ] 统一扩展名获取逻辑
- [ ] 复用 constants.js
### 后端代码
- [ ] 简化 handleLocalFileRequest
- [ ] 提取配置到独立文件
- [ ] 添加单元测试
- [ ] 统一错误处理
---
## 七、后续行动
1. **立即执行** (1-2 天)
- 移除调试代码
- 删除重复代码
- 简化函数逻辑
2. **短期计划** (1 周)
- 拆分 FileSystem.vue
- 提取 composables
- 统一工具函数
3. **长期优化** (2-4 周)
- TypeScript 迁移
- 添加单元测试
- 性能优化
---
## 八、参考资源
- [Vue 3 风格指南](https://vuejs.org/style-guide/)
- [代码整洁之道](https://www.oreilly.com/library/view/clean-code-a/9780136083238/)
- [重构:改善既有代码的设计](https://www.refactoring.com/)