# 新旧组件对比

## 原始实现 (StudentAnswerSheetViewer.vue)

### 特点
- ✅ 功能完整，支持编辑和预览
- ✅ 使用 TemplateEditor 和 TemplatePreview 组件
- ✅ 复用了大量答题卡模板编辑器的功能
- ❌ 依赖关系复杂（TemplateEditor, KonvaAreaRenderer, StepHeaderPanel 等）
- ❌ 包含大量编辑相关的代码和逻辑
- ❌ 代码量大（~800+ 行）

### 依赖组件
```
StudentAnswerSheetViewer
  └── TemplateEditor (821行)
        ├── TemplatePreview (414行)
        ├── TemplateToolbar
        ├── KonvaAreaRenderer
        └── StepHeaderPanel
```

### 依赖工具函数
- `useTemplateDataConverter` - 模板数据转换
- `useRawInfoParser` - 原始数据解析
- `useMarkingOverlay` - 标记叠加
- `useMarkingTools` - 标记工具
- `useEditorSettings` - 编辑器设置
- `useEditorValidation` - 编辑器验证

### 使用复杂度
```vue
<TemplateEditor
  :template-data="templateData"
  :ai-template-data="aiTemplateData"
  :readonly="true"
  :preview="false"
  :is-embedded="true"
  :show-toolbar="false"
  :enable-marking-overlay="true"
  :marking-overlay-data="markingOverlayData"
  :marking-overlay-options="{ ... }"
  :initial-step="EditorStep.OBJECTIVE"
/>
```

## 新实现 (AnswerSheetWithMarking.vue)

### 特点
- ✅ 专注于查看，不支持编辑
- ✅ 零依赖其他答题卡组件
- ✅ 代码简洁（~300 行）
- ✅ 易于理解和维护
- ✅ 适合在 App 中使用
- ✅ 性能更好（减少不必要的计算）

### 依赖关系
```
AnswerSheetWithMarking (独立组件)
  ├── useMarkingRenderer (渲染逻辑)
  └── useDataParser (数据解析)
```

### 使用复杂度
```vue
<AnswerSheetWithMarking 
  :data="answerSheetData" 
  :loading="loading" 
  :error="error" 
/>
```

## 代码对比

### 原始实现的数据流
1. API 数据 → parseRawInfo → AITemplateResults
2. AITemplateResults → convertFromAI → InternalTemplateData
3. 主观题答案 → createMarkingOverlayFromStudentData → MarkingOverlayConfig[]
4. TemplateEditor 接收 templateData + aiTemplateData + markingOverlayData
5. TemplateEditor 内部使用 useMarkingOverlay 渲染

### 新实现的数据流
1. API 数据 → parseAnswerSheetData → AnswerSheetData
2. AnswerSheetWithMarking 接收 AnswerSheetData
3. 组件内部使用 useMarkingRenderer 直接渲染

## 功能对比表

| 功能 | 原始实现 | 新实现 |
|------|---------|--------|
| 显示答题卡图片 | ✅ | ✅ |
| 显示批注标记 | ✅ | ✅ |
| 显示得分/满分 | ✅ | ✅ |
| 显示老师名称 | ✅ | ✅ |
| 显示总分 | ✅ | ✅ |
| 翻页功能 | ✅ | ✅ |
| 缩放功能 | ✅ | ✅ (自动) |
| 旋转功能 | ✅ | ❌ |
| 编辑批注 | ❌ (readonly) | ❌ |
| 工具栏 | ✅ (隐藏) | ❌ |
| 代码行数 | ~2000+ | ~500 |
| 依赖组件数 | 10+ | 0 |

## 性能对比

### 渲染性能
- **原始实现**: 需要初始化完整的编辑器环境，包括 Konva Stage/Layer、编辑器状态管理等
- **新实现**: 只初始化必要的 Konva Stage/Layer，直接渲染标记

### 内存占用
- **原始实现**: 较高（包含编辑器的各种状态和功能）
- **新实现**: 较低（只保存必要的显示数据）

### 加载速度
- **原始实现**: 较慢（需要加载多个组件和工具函数）
- **新实现**: 较快（单一组件，依赖少）

## 适用场景

### 原始实现适合
- 需要在 Web 端查看答题卡
- 可能需要编辑功能的场景
- 需要复用答题卡编辑器的其他功能

### 新实现适合
- ✅ App 端查看答题卡
- ✅ 仅需要查看，不需要编辑
- ✅ 对性能和包体积有要求
- ✅ 希望代码简洁易维护

## 迁移建议

如果当前使用 `StudentAnswerSheetViewer`，可以这样迁移到新组件：

```vue
<!-- 旧代码 -->
<StudentAnswerSheetViewer :info-id="infoId" />

<!-- 新代码 -->
<AnswerSheetWithMarking :data="answerSheetData" />

<script setup>
import { useQuery } from '@tanstack/vue-query';
import { AnswerSheetWithMarking, useDataParser } from '@/components/answer-sheet-viewer';

const { data: apiData } = useQuery({
  queryKey: ['answerSheet', infoId],
  queryFn: () => api.getAnswerSheetDetail(infoId)
});

const { parseAnswerSheetData } = useDataParser();
const answerSheetData = computed(() => 
  apiData.value ? parseAnswerSheetData(apiData.value) : null
);
</script>
```

## 总结

新组件通过以下方式实现简化：

1. **移除编辑功能** - 只保留查看相关代码
2. **扁平化数据结构** - 不需要复杂的 AI 模板数据转换
3. **直接渲染** - 不通过多层组件传递数据
4. **独立实现** - 不依赖答题卡编辑器的任何代码

适合在 App 中使用，代码更简洁、性能更好、易于维护。


