重构:文件系统模块化架构,增强 Markdown 渲染
- 拆分 FileSystem.vue 为模块化组件架构 - 新增 Markdown Mermaid 图表渲染支持 - 新增 180+ 编程语言代码高亮 - 修复编辑/预览模式切换渲染问题 - 优化亮色/暗色模式主题适配 - 新增 TypeScript 类型定义
This commit is contained in:
628
docs/代码审查/refactoring-review-2026-01-30.md
Normal file
628
docs/代码审查/refactoring-review-2026-01-30.md
Normal file
@@ -0,0 +1,628 @@
|
||||
# 重构缺漏检查报告
|
||||
**日期**: 2025-01-30
|
||||
**审查范围**: FileSystem.vue + 3个Composables
|
||||
|
||||
---
|
||||
|
||||
## 一、严重问题 🔴
|
||||
|
||||
### 1. **重构目标未达成 - FileSystem.vue 仍然过大**
|
||||
|
||||
| 文件 | 当前行数 | 目标行数 | 差距 | 状态 |
|
||||
|------|----------|----------|------|------|
|
||||
| FileSystem.vue | 4047 | < 500 | +3547 | 🔴 |
|
||||
| useNavigation.js | 273 | - | - | ✅ |
|
||||
| useFileEdit.js | 369 | - | - | ✅ |
|
||||
| useFilePreview.js | 611 | - | - | ✅ |
|
||||
| **总计** | 5300 | < 1500 | +3800 | 🔴 |
|
||||
|
||||
**问题**:
|
||||
- Composables已创建(1253行),但**未真正集成**
|
||||
- FileSystem.vue仍然包含所有原始逻辑(4047行)
|
||||
- **代码总量增加**:从4241行 → 5300行(+25%)
|
||||
|
||||
**根本原因**:
|
||||
- 之前因20+个重复函数声明错误,撤销了composable集成
|
||||
- 保留了所有本地实现,导致双重代码存在
|
||||
|
||||
---
|
||||
|
||||
### 2. **重复的计算属性(DRY违反)**
|
||||
|
||||
#### 问题1: `isFileModified` 重复定义
|
||||
|
||||
**FileSystem.vue:2977-2988**
|
||||
```javascript
|
||||
const isFileModified = computed(() => {
|
||||
const hasContent = fileContent.value !== '' && fileContent.value.trim() !== ''
|
||||
const hasModified = selectedFilePath.value && fileContent.value !== originalContent.value
|
||||
const isNewFile = !selectedFilePath.value && hasContent
|
||||
return isEditableView.value && (hasModified || isNewFile)
|
||||
})
|
||||
```
|
||||
|
||||
**useFileEdit.js:71-74** (未使用)
|
||||
```javascript
|
||||
const isFileModified = computed(() => {
|
||||
return originalContent.value !== undefined &&
|
||||
originalContent.value !== fileContent.value
|
||||
})
|
||||
```
|
||||
|
||||
**差异**:FileSystem.vue版本包含"新建文件"逻辑,useFileEdit版本更简单
|
||||
|
||||
---
|
||||
|
||||
#### 问题2: 文件名计算属性重复
|
||||
|
||||
**FileSystem.vue:1437-1460**
|
||||
```javascript
|
||||
const currentFileNameDisplay = computed(() => {
|
||||
if (!selectedFilePath.value && !filePath.value) return '无文件'
|
||||
|
||||
const path = selectedFilePath.value || filePath.value
|
||||
const parts = path.split(/[/\\]/)
|
||||
const fileName = parts[parts.length - 1]
|
||||
|
||||
if (fileName.length > 30) {
|
||||
return fileName.substring(0, 15) + '...' + fileName.substring(fileName.length - 10)
|
||||
}
|
||||
return fileName
|
||||
})
|
||||
```
|
||||
|
||||
**useFilePreview.js:122-126** (未使用)
|
||||
```javascript
|
||||
const currentFileName = computed(() => {
|
||||
if (!filePath.value) return ''
|
||||
const parts = filePath.value.split(/[/\\]/)
|
||||
return parts[parts.length - 1]
|
||||
})
|
||||
```
|
||||
|
||||
**重复**:都做路径分割取文件名,但Display版本有截断逻辑
|
||||
|
||||
---
|
||||
|
||||
#### 问题3: 文件路径计算属性重复
|
||||
|
||||
**FileSystem.vue:1462-1485**
|
||||
```javascript
|
||||
const currentFileFullPathDisplay = computed(() => {
|
||||
if (isBrowsingZip.value) {
|
||||
return `ZIP: ${currentZipPath.value} → ${currentZipDirectory.value || '/'}`
|
||||
}
|
||||
|
||||
if (!selectedFilePath.value) {
|
||||
return filePath.value || '未选择文件'
|
||||
}
|
||||
|
||||
const path = selectedFilePath.value
|
||||
if (path.length > 50) {
|
||||
return '...' + path.substring(path.length - 50)
|
||||
}
|
||||
return path
|
||||
})
|
||||
```
|
||||
|
||||
**useFilePreview.js:131** (未使用)
|
||||
```javascript
|
||||
const currentFileFullPath = computed(() => filePath.value || '')
|
||||
```
|
||||
|
||||
**重复**:获取文件路径,但Display版本有ZIP模式和截断逻辑
|
||||
|
||||
---
|
||||
|
||||
#### 问题4: 内容修改检测重复
|
||||
|
||||
**FileSystem.vue:2991-2994**
|
||||
```javascript
|
||||
const contentChanged = computed(() => {
|
||||
return fileContent.value !== '' &&
|
||||
fileContent.value !== originalContent.value
|
||||
})
|
||||
```
|
||||
|
||||
**useFileEdit.js:79-82** (未使用)
|
||||
```javascript
|
||||
const contentChanged = computed(() => {
|
||||
return fileContent.value !== '' &&
|
||||
fileContent.value !== originalContent.value
|
||||
})
|
||||
```
|
||||
|
||||
**完全相同**:100%重复代码
|
||||
|
||||
---
|
||||
|
||||
#### 问题5: 保存/重置按钮状态重复
|
||||
|
||||
**FileSystem.vue:2997-3004**
|
||||
```javascript
|
||||
const canSaveFile = computed(() => isEditableView.value && contentChanged.value)
|
||||
const canResetContent = computed(() =>
|
||||
isEditableView.value &&
|
||||
contentChanged.value &&
|
||||
originalContent.value !== undefined
|
||||
)
|
||||
```
|
||||
|
||||
**useFileEdit.js:87-98** (未使用)
|
||||
```javascript
|
||||
const canSaveFile = computed(() => {
|
||||
return isEditMode.value && contentChanged.value
|
||||
})
|
||||
|
||||
const canResetContent = computed(() => {
|
||||
return isEditMode.value &&
|
||||
contentChanged.value &&
|
||||
originalContent.value !== undefined
|
||||
})
|
||||
```
|
||||
|
||||
**差异**:FileSystem.vue用`isEditableView`,useFileEdit用`isEditMode`
|
||||
|
||||
---
|
||||
|
||||
### 3. **调试日志仍然过多 - 65个**
|
||||
|
||||
```bash
|
||||
$ grep -c "debug(Log|Warn|Error|Info)" web/src/components/FileSystem.vue
|
||||
65
|
||||
```
|
||||
|
||||
**分布**:
|
||||
- `debugLog`: ~45处
|
||||
- `debugWarn`: ~12处
|
||||
- `debugError`: ~8处
|
||||
|
||||
**问题**:
|
||||
- 已从raw console替换为debugLog,但**数量仍然过多**
|
||||
- 过度防御性编程,每个分支都记录日志
|
||||
- 影响代码可读性和运行时性能
|
||||
|
||||
---
|
||||
|
||||
## 二、中等问题 🟡
|
||||
|
||||
### 4. **currentFileExtension 逻辑嵌套过多**
|
||||
|
||||
**FileSystem.vue:2941-2960** (19行)
|
||||
```javascript
|
||||
const currentFileExtension = computed(() => {
|
||||
const path = selectedFilePath.value || filePath.value
|
||||
if (!path) return ''
|
||||
|
||||
const fileName = path.split(/[/\\]/).pop()?.toLowerCase() || ''
|
||||
const specialFiles = {
|
||||
'dockerfile': 'dockerfile',
|
||||
'containerfile': 'dockerfile',
|
||||
'makefile': 'makefile',
|
||||
'cmakelists.txt': 'cmake',
|
||||
'.gitignore': 'gitignore',
|
||||
'.env': 'properties',
|
||||
}
|
||||
|
||||
if (specialFiles[fileName]) return specialFiles[fileName]
|
||||
return getExt(path)
|
||||
})
|
||||
```
|
||||
|
||||
**可以改进为**(使用fileHelpers.js中的函数):
|
||||
```javascript
|
||||
const currentFileExtension = computed(() => {
|
||||
const path = selectedFilePath.value || filePath.value
|
||||
return getExtensionForHighlight(path) // 复用现有工具函数
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. **函数命名不一致**
|
||||
|
||||
| FileSystem.vue | useFilePreview.js | 用途 |
|
||||
|----------------|-------------------|------|
|
||||
| `currentFileNameDisplay` | `currentFileName` | 获取文件名 |
|
||||
| `currentFileFullPathDisplay` | `currentFileFullPath` | 获取完整路径 |
|
||||
| `currentImageDimensionsLocal` | `currentImageDimensions` | 图片尺寸 |
|
||||
|
||||
**问题**:
|
||||
- 有的带`Display`后缀,有的不带
|
||||
- 有的带`Local`后缀,含义不明
|
||||
- 命名不一致导致维护困难
|
||||
|
||||
---
|
||||
|
||||
### 6. **Go代码配置函数重复**
|
||||
|
||||
**internal/filesystem/config.go:256-295**
|
||||
```go
|
||||
func getAllowedExtensions() map[string]bool {
|
||||
return map[string]bool{
|
||||
".jpg": true, ".jpeg": true, ".png": true,
|
||||
// ... 30+ 个硬编码扩展名
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**web/src/utils/constants.js:27-73** (重复定义)
|
||||
```javascript
|
||||
export const FILE_EXTENSIONS = {
|
||||
IMAGE: ['jpg', 'jpeg', 'png', /* ... */],
|
||||
VIDEO_BROWSER: ['mp4', 'webm', /* ... */],
|
||||
// ... 类似的30+个扩展名
|
||||
}
|
||||
```
|
||||
|
||||
**问题**:前后端用不同格式重复定义相同的数据
|
||||
|
||||
**建议**:后端从配置文件加载,或生成JSON供前端使用
|
||||
|
||||
---
|
||||
|
||||
## 三、代码规范问题 ⚠️
|
||||
|
||||
### 7. **路径分隔符正则重复**
|
||||
|
||||
**出现次数**: 15+
|
||||
|
||||
```javascript
|
||||
// FileSystem.vue 多处
|
||||
path.split(/[/\\]/) // 行 719, 798, 819, 833, 845, 2946, ...
|
||||
|
||||
// useFilePreview.js:124
|
||||
path.split(/[/\\/]/)
|
||||
|
||||
// useNavigation.js:304
|
||||
const parts = path.split(/[/\\]/)
|
||||
```
|
||||
|
||||
**建议**:提取为共享常量
|
||||
```javascript
|
||||
// utils/pathConstants.js
|
||||
export const PATH_SEPARATOR_REGEX = /[/\\]/
|
||||
export const splitPath = (path) => path.split(PATH_SEPARATOR_REGEX)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. **文件类型判断分散**
|
||||
|
||||
**FileSystem.vue:857-869**
|
||||
```javascript
|
||||
const previewableTypes = [
|
||||
...FILE_EXTENSIONS.IMAGE,
|
||||
...FILE_EXTENSIONS.VIDEO_BROWSER,
|
||||
...FILE_EXTENSIONS.AUDIO,
|
||||
'pdf', 'html', 'htm', 'md', 'markdown'
|
||||
]
|
||||
|
||||
const knownBinaryTypes = [
|
||||
'exe', 'dll', 'so', 'bin',
|
||||
'zip', 'rar', '7z', 'tar', 'gz', 'iso', 'img', 'dmg',
|
||||
'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'
|
||||
]
|
||||
```
|
||||
|
||||
**问题**:
|
||||
- 内联定义在函数内部
|
||||
- 应该定义在constants.js中复用
|
||||
|
||||
---
|
||||
|
||||
### 9. **localStorage键名分散**
|
||||
|
||||
**多处重复定义**:
|
||||
- FileSystem.vue: 使用`STORAGE_KEYS.FILESYSTEM.*`
|
||||
- useFileEdit.js: 直接定义`DRAFT_STORAGE_KEY`
|
||||
- useNavigation.js: 直接定义`STORAGE_KEY_PATH_HISTORY`
|
||||
|
||||
**应该统一使用**:`STORAGE_KEYS`常量对象
|
||||
|
||||
---
|
||||
|
||||
## 四、DRY原则违反统计
|
||||
|
||||
### 重复代码统计
|
||||
|
||||
| 类型 | 重复次数 | 总行数 | 浪费 |
|
||||
|------|----------|--------|------|
|
||||
| 计算属性 | 5组 | ~80行 | 40行 |
|
||||
| 路径分割正则 | 15+次 | ~15行 | 14行 |
|
||||
| 文件类型判断 | 8+次 | ~50行 | 40行 |
|
||||
| localStorage键 | 6+处 | ~12行 | 8行 |
|
||||
| **总计** | **34+处** | **~157行** | **102行** |
|
||||
|
||||
---
|
||||
|
||||
## 五、优化建议
|
||||
|
||||
### 优先级1: 立即修复 🔴
|
||||
|
||||
#### 1.1 移除未使用的Composables
|
||||
```bash
|
||||
# 由于composables未被实际使用,应该删除或文档化
|
||||
rm web/src/composables/useNavigation.js
|
||||
rm web/src/composables/useFileEdit.js
|
||||
rm web/src/composables/useFilePreview.js
|
||||
```
|
||||
|
||||
**理由**:如果不用,就不应该存在,避免混淆
|
||||
|
||||
---
|
||||
|
||||
#### 1.2 删除重复计算属性
|
||||
|
||||
**FileSystem.vue - 保留更完整的版本,删除useFileEdit/useFilePreview中的**:
|
||||
|
||||
```javascript
|
||||
// 保留 FileSystem.vue:1437 - currentFileNameDisplay (有截断逻辑)
|
||||
// 保留 FileSystem.vue:1462 - currentFileFullPathDisplay (有ZIP模式)
|
||||
// 保留 FileSystem.vue:2977 - isFileModified (有新建文件逻辑)
|
||||
// 删除 useFileEdit.js:71, useFilePreview.js:122-126 等重复定义
|
||||
```
|
||||
|
||||
**或者相反**:如果决定使用composables,则删除FileSystem.vue中的重复定义
|
||||
|
||||
---
|
||||
|
||||
#### 1.3 大幅减少调试日志
|
||||
|
||||
**策略A: 环境变量控制**(已部分实现)
|
||||
```javascript
|
||||
// utils/debugLog.js
|
||||
const ENABLE_DEBUG = import.meta.env.DEV
|
||||
|
||||
export const debugLog = ENABLE_DEBUG ? console.log : () => {}
|
||||
export const debugWarn = ENABLE_DEBUG ? console.warn : () => {}
|
||||
export const debugError = console.error // 始终保留错误日志
|
||||
```
|
||||
|
||||
**策略B: 删除非关键日志**(推荐)
|
||||
```javascript
|
||||
// 删除这些类型的日志:
|
||||
debugLog('[readFile] 开始读取文件') // 显而易见的操作
|
||||
debugLog('[handleKeyDown] F2 pressed') // 用户操作
|
||||
debugLog('[startResizeHorizontal] 开始拖拽') // UI交互
|
||||
|
||||
// 保留这些:
|
||||
debugError('[readFile] 读取失败:', error) // 错误
|
||||
debugWarn('[loadCommonPaths] Wails API未就绪') // 降级场景
|
||||
```
|
||||
|
||||
**目标**: 从65个 → < 10个(只保留错误和关键警告)
|
||||
|
||||
---
|
||||
|
||||
### 优先级2: 短期优化 🟡
|
||||
|
||||
#### 2.1 提取共享工具函数
|
||||
|
||||
**创建 web/src/utils/pathHelpers.js**:
|
||||
```javascript
|
||||
export const PATH_SEPARATOR_REGEX = /[/\\]/
|
||||
|
||||
export const splitPath = (path) => path.split(PATH_SEPARATOR_REGEX)
|
||||
|
||||
export const getFileName = (path) => {
|
||||
if (!path) return ''
|
||||
const parts = splitPath(path)
|
||||
return parts[parts.length - 1] || path
|
||||
}
|
||||
|
||||
export const getParentPath = (path) => {
|
||||
if (!path) return ''
|
||||
const lastSep = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'))
|
||||
return lastSep > 0 ? path.substring(0, lastSep) : path
|
||||
}
|
||||
```
|
||||
|
||||
**替换所有** `path.split(/[/\\]/)` 为 `splitPath(path)`
|
||||
|
||||
---
|
||||
|
||||
#### 2.2 统一文件类型常量
|
||||
|
||||
**创建 web/src/utils/fileTypeCategories.js**:
|
||||
```javascript
|
||||
import { FILE_EXTENSIONS } from './constants'
|
||||
|
||||
export const PREVIEWABLE_TYPES = [
|
||||
...FILE_EXTENSIONS.IMAGE,
|
||||
...FILE_EXTENSIONS.VIDEO_BROWSER,
|
||||
...FILE_EXTENSIONS.AUDIO,
|
||||
'pdf', 'html', 'htm', 'md', 'markdown'
|
||||
]
|
||||
|
||||
export const KNOWN_BINARY_TYPES = [
|
||||
'exe', 'dll', 'so', 'bin',
|
||||
'zip', 'rar', '7z', 'tar', 'gz', 'iso', 'img', 'dmg',
|
||||
'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'
|
||||
]
|
||||
|
||||
export const TEXT_EDITABLE_TYPES = [
|
||||
...FILE_EXTENSIONS.TEXT,
|
||||
...FILE_EXTENSIONS.CODE
|
||||
]
|
||||
```
|
||||
|
||||
**替换所有内联定义**
|
||||
|
||||
---
|
||||
|
||||
#### 2.3 统一localStorage键名
|
||||
|
||||
**只在 constants.js 中定义一次**:
|
||||
```javascript
|
||||
export const STORAGE_KEYS = {
|
||||
FILESYSTEM: {
|
||||
PATH_HISTORY: 'app-filesystem-path-history',
|
||||
EDIT_MODE: 'app-filesystem-edit-mode',
|
||||
PANEL_WIDTH: 'app-filesystem-panel-width',
|
||||
DRAFT_CONTENT: 'filesystem-draft-content',
|
||||
DRAFT_TIME: 'filesystem-draft-time',
|
||||
FAVORITE_FILES: 'filesystem-favorite-files',
|
||||
}
|
||||
}
|
||||
|
||||
// 删除所有其他文件中的重复定义
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 优先级3: 长期重构 🔵
|
||||
|
||||
#### 3.1 真正拆分FileSystem.vue
|
||||
|
||||
**目标**: 从4047行 → < 500行
|
||||
|
||||
**策略**:
|
||||
1. **提取子组件** (~1500行)
|
||||
- `FileListPanel.vue` (文件列表, ~300行)
|
||||
- `CodeEditorPanel.vue` (编辑器面板, ~400行)
|
||||
- `PreviewPanel.vue` (预览面板, ~300行)
|
||||
- `FavoriteSidebar.vue` (收藏夹侧边栏, ~200行)
|
||||
- `Toolbar.vue` (顶部工具栏, ~150行)
|
||||
- `ContextMenu.vue` (右键菜单, ~150行)
|
||||
|
||||
2. **提取composables** (~1000行)
|
||||
- `useFileSystem.js` (核心文件系统操作, ~300行)
|
||||
- `useFileEditor.js` (编辑器逻辑, ~200行)
|
||||
- `useFilePreview.js` (预览逻辑, ~250行)
|
||||
- `useFavoriteFiles.js` (收藏夹管理, ~150行)
|
||||
- `useKeyboardShortcuts.js` (快捷键, ~100行)
|
||||
|
||||
3. **主组件保留** (~500行)
|
||||
- 布局和状态协调
|
||||
- 子组件通信
|
||||
- 生命周期管理
|
||||
|
||||
**时间估算**: 2-3周
|
||||
|
||||
---
|
||||
|
||||
#### 3.2 TypeScript迁移
|
||||
|
||||
**目标**: 添加类型安全,减少运行时错误
|
||||
|
||||
```typescript
|
||||
// types/file.ts
|
||||
export interface FileItem {
|
||||
path: string
|
||||
name: string
|
||||
is_dir: boolean
|
||||
size: number
|
||||
modified: string
|
||||
}
|
||||
|
||||
export interface PreviewState {
|
||||
isImageView: boolean
|
||||
isVideoView: boolean
|
||||
isAudioView: boolean
|
||||
isPdfFile: boolean
|
||||
isHtmlFile: boolean
|
||||
isMarkdownFile: boolean
|
||||
isBinaryFile: boolean
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 3.3 统一前后端文件类型定义
|
||||
|
||||
**方案A: 后端生成JSON**
|
||||
```go
|
||||
// internal/filesystem/export_types.go
|
||||
func ExportFileTypes() string {
|
||||
types := map[string][]string{
|
||||
"image": getAllowedExtensions(),
|
||||
"binary": getForbiddenExtensions(),
|
||||
}
|
||||
json, _ := json.Marshal(types)
|
||||
return string(json)
|
||||
}
|
||||
```
|
||||
|
||||
**方案B: 独立配置文件**
|
||||
```yaml
|
||||
# config/file_types.yaml
|
||||
image:
|
||||
- jpg
|
||||
- jpeg
|
||||
- png
|
||||
binary:
|
||||
- exe
|
||||
- dll
|
||||
```
|
||||
|
||||
前后端都从同一配置读取
|
||||
|
||||
---
|
||||
|
||||
## 六、检查清单
|
||||
|
||||
### 立即执行(本周)
|
||||
|
||||
- [ ] **决定**: 删除还是使用composables
|
||||
- [ ] **删除重复**: 移除5组重复计算属性(102行)
|
||||
- [ ] **减少日志**: 从65个debugLog → < 10个
|
||||
- [ ] **提取工具**: 创建pathHelpers.js
|
||||
- [ ] **统一常量**: 合并文件类型定义
|
||||
- [ ] **统一键名**: 只使用STORAGE_KEYS
|
||||
|
||||
### 短期计划(2周)
|
||||
|
||||
- [ ] **提取子组件**: FileListPanel, Toolbar, ContextMenu
|
||||
- [ ] **提效composables**: 真正集成useFileSystem, useFilePreview
|
||||
- [ ] **优化函数**: 简化currentFileExtension逻辑
|
||||
- [ ] **命名统一**: 统一Display/Local后缀规则
|
||||
|
||||
### 长期优化(1个月)
|
||||
|
||||
- [ ] **组件化**: 完成所有子组件提取
|
||||
- [ ] **TypeScript**: 添加类型定义
|
||||
- [ ] **前后端统一**: 文件类型配置共享
|
||||
- [ ] **单元测试**: 覆盖核心逻辑
|
||||
|
||||
---
|
||||
|
||||
## 七、代码质量指标(更新后)
|
||||
|
||||
| 指标 | 当前值 | 目标值 | 评级 |
|
||||
|------|--------|--------|------|
|
||||
| 单文件最大行数 | 4047 | < 500 | 🔴 |
|
||||
| 函数平均行数 | ~50 | < 30 | 🟡 |
|
||||
| 代码重复率 | ~8% | < 3% | 🔴 |
|
||||
| 调试语句数量 | 65 | < 10 | 🔴 |
|
||||
| 圈复杂度 | 15+ | < 10 | 🟡 |
|
||||
| 未使用代码 | 1253行 | 0 | 🔴 |
|
||||
|
||||
---
|
||||
|
||||
## 八、总结
|
||||
|
||||
### 关键发现
|
||||
|
||||
1. **重构未完成**: Composables已创建但未使用,反而增加了总代码量
|
||||
2. **重复代码严重**: 5组计算属性重复,102行浪费
|
||||
3. **过度防御性编程**: 65个调试日志,远超必要数量
|
||||
4. **命名不一致**: Display/Local后缀混乱
|
||||
|
||||
### 下一步行动
|
||||
|
||||
**推荐方案A: 激进重构**
|
||||
- 删除3个未使用的composables
|
||||
- 立即开始拆分子组件
|
||||
- 1个月内完成组件化
|
||||
|
||||
**推荐方案B: 渐进优化(更稳妥)**
|
||||
- 先清理重复代码和日志
|
||||
- 提取共享工具函数
|
||||
- 逐步拆分子组件
|
||||
|
||||
### 风险提示
|
||||
|
||||
⚠️ **当前状态**: 代码库处于"半重构"状态,既有旧实现又有新参考,容易造成混淆
|
||||
|
||||
**建议**: 尽快决定方向(彻底重构 vs 回滚到重构前),避免技术债务累积
|
||||
Reference in New Issue
Block a user