# 文件查看模块 — 上传任务列表功能 实施计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 在 ReadModule 中嵌入上传任务列表组件,实现文件上传后自动跟踪向量化+出题状态,支持轮询刷新、分页、筛选,基于文件管理接口文档中的 `processStepStatus`/`examStatus` 字段。
**Architecture:** 新建 `useUploadTasks.js` composable 管理全部状态和轮询逻辑;新建 `UploadTaskPanel.vue` 面板容器 + `UploadTaskItem.vue` 任务卡片;修改 `ReadModule.vue` 嵌入面板并联动上传成功事件。复用现有 `fileAPI.getFiles()` 接口获取数据,无需新增后端接口。
**Tech Stack:** Vue 3 Composition API (`
```
---
### Task 3: 创建 UploadTaskPanel.vue
**Files:**
- Create: `src/components/exam/UploadTaskPanel.vue`
- [ ] **Step 1: 创建完整组件(Template + Script + Style)**
```html
```
---
## Phase 3: ReadModule 集成
### Task 4: 补全 mapBackendToFrontend 字段映射
**Files:**
- Modify: `src/components/ReadModule.vue:1388-1414` (mapBackendToFrontend 函数)
- [ ] **Step 1: 在 mapBackendToFrontend 返回对象中添加 4 个状态字段**
在现有返回对象的 `fileCategory: backendFile.fileCategory` 之后添加:
```javascript
// 处理状态字段(用于上传任务追踪)
processStepStatus: backendFile.processStepStatus || backendFile.process_step_status || '',
processStepMessage: backendFile.processStepMessage || backendFile.process_step_message || '',
examStatus: backendFile.examStatus || backendFile.exam_status || '',
processMessage: backendFile.processMessage || backendFile.process_message || '',
```
---
### Task 5: 在 ReadModule 中嵌入 UploadTaskPanel
**Files:**
- Modify: `src/components/ReadModule.vue`
- Template 区域:在 Tab 栏下方添加面板
- Script 区域:引入 composable 和组件,绑定上传成功事件
- [ ] **Step 1: 添加 import 语句**
在现有的 `import` 块中(约 L1072 之后)添加:
```javascript
import UploadTaskPanel from './exam/UploadTaskPanel.vue'
import { useUploadTasks } from './exam/composables/useUploadTasks.js'
```
同时确保以下图标已导入(如果没有则添加):
```javascript
ReloadOutlined, InboxOutlined, LoadingOutlined, CheckCircleOutlined,
CloseCircleOutlined, ClockCircleOutlined, MinusCircleOutlined, QuestionCircleOutlined
```
- [ ] **Step 2: 添加 composable 初始化**
在 `onMounted` 之前(约 L2123 之前)添加:
```javascript
// 上传任务管理
const showTaskPanel = ref(false)
const {
tasks: uploadTasks,
loading: taskLoading,
polling: taskPolling,
statusFilter: taskStatusFilter,
searchQuery: taskSearchQuery,
currentPage: taskCurrentPage,
stats: taskStats,
paginatedTasks: taskPaginatedTasks,
totalFilteredPages: taskTotalPages,
parseVectorStatus,
parseExamStatus,
addTask: addUploadTask,
fetchTasks: fetchUploadTasks,
refreshTasks: refreshUploadTasks,
startPolling: startTaskPolling,
stopPolling: stopTaskPolling
} = useUploadTasks()
```
- [ ] **Step 3: 修改 handleUploadSubmit 成功回调**
将现有的上传成功代码块(约 L2363-L2377)修改为:
```javascript
if (response.data.code === 200) {
const uploadedFile = response.data.data
const fileTypeText = uploadForm.isPublic ? '公开文件' : '个人文件'
let successMsg = `${fileTypeText}"${uploadForm.file.name}"上传成功!`
if (!isAdminUser(userInfo.value) && uploadForm.isPublic) {
successMsg += ' 文件已进入待审批队列,请等待管理员审核!'
}
message.success(successMsg)
closeUploadModal()
// 添加到上传任务列表
addUploadTask(uploadedFile)
showTaskPanel.value = true
startTaskPolling()
await loadFileList(null, true)
if (canApproveFile.value) {
loadPendingFiles()
}
} else {
```
- [ ] **Step 4: 在模板中添加 UploadTaskPanel 组件**
在 `
` 标签之后、内容区之前插入:
```html
```
同时在工具栏区域(上传按钮附近)添加一个入口按钮:
```html
```
- [ ] **Step 5: 在 onMounted 中初始化任务列表**
在 `onMounted` 的最后(约 L2143 之前)添加:
```javascript
// 加载上传任务列表(如果有未完成的任务)
await fetchUploadTasks()
if (tasks.value.some(t => {
const pss = t.processStepStatus
return ['UPLOADED','VECTORIZING','EXAM_GENERATING'].includes(pss)
})) {
showTaskPanel.value = true
startTaskPolling()
}
```
注意:这里需要使用 composable 内部的 `tasks` 引用。由于 composable 已经导出了 `tasks`,直接使用即可。
---
## Phase 4: 验证
### Task 6: 构建验证与功能回归测试
**Files:** 无新建文件
- [ ] **Step 1: 运行前端构建验证**
Run: `npm run build`
Expected: Vite 构建成功,零编译错误
- [ ] **Step 2: VS Code 诊断检查**
对以下文件运行 GetDiagnostics,确认零错误:
- `src/components/exam/composables/useUploadTasks.js`
- `src/components/exam/UploadTaskPanel.vue`
- `src/components/exam/UploadTaskItem.vue`
- `src/components/ReadModule.vue`
- [ ] **Step 3: 功能清单验证**
逐一确认以下功能路径正常工作:
- [ ] 上传文件后自动弹出任务面板
- [ ] 任务面板显示正确的文件信息(名称、大小、部门、时间)
- [ ] 向量化状态正确显示(等待→处理中动画→成功/失败)
- [ ] 出题状态正确显示(未开始→处理中动画→成功含题目数/失败含错误消息)
- [ ] 错误消息可展开/收起查看详情
- [ ] 统计标签栏数字准确(全部/处理中/成功/失败)
- [ ] 点击统计标签可筛选对应状态的任务
- [ ] 搜索框支持按文件名和部门名搜索
- [ ] 分页器正常工作
- [ ] 手动刷新按钮可触发重新加载
- [ ] 自动轮询在有"处理中"任务时启动,全部完成后停止
- [ ] 关闭面板后再打开,数据保持不变
- [ ] 现有文件列表功能不受影响(部门筛选、分类切换等)
- [ ] **Step 4: 清理调试日志**
移除所有 `console.log` 调试语句(保留 `console.error`),包括:
- `useUploadTasks.js` 中的 `console.log('📋 [任务刷新]...')`
- `ReadModule.vue` 中之前添加的部门筛选调试日志(如果还在)
---
## 自检清单
### Spec 覆盖度
| 设计文档需求 | 对应 Task | 状态 |
|------------|----------|------|
| 集成上传任务列表组件 | Task 3 + Task 5 | ✅ |
| 解析 processStepMessage 判断向量化状态 | Task 1 Step 2 | ✅ |
| 解析 processMessage 判断出题状态 | Task 1 Step 3 | ✅ |
| 向量化成功/失败状态展示 | Task 2 | ✅ |
| 出题成功/失败状态展示 | Task 2 | ✅ |
| 处理中状态(带动画) | Task 2 | ✅ |
| 实时更新(自动轮询) | Task 1 Step 6 | ✅ |
| 分页功能 | Task 1 Step 5 + Task 3 | ✅ |
| 状态筛选功能 | Task 1 Step 5 + Task 3 | ✅ |
| 手动刷新按钮 | Task 3 | ✅ |
| 符合现有 UI/UX 规范(design-tokens) | Task 2 + Task 3 CSS | ✅ |
| 嵌入 ReadModule | Task 5 | ✅ |
| 上传后自动加入任务列表 | Task 5 Step 3 | ✅ |
### 占位符扫描
- [ ] 无 TBD/TODO 占位符
- [ ] 无 "类似 Task N" 引用
- [ ] 所有代码步骤包含完整实现
### 类型一致性
- [ ] `parseVectorStatus` / `parseExamStatus` 在 Task 1 定义,Task 2/3 通过 props 传递一致
- [ ] composable 导出名称在 Task 1 定义,Task 5 解构使用一致
- [ ] CSS 变量使用 design-tokens.css 中实际存在的变量名