# 文件查看模块 — 上传任务列表功能 实施计划 > **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 中实际存在的变量名