2026-03-05 10:39:35 +08:00
|
|
|
|
# 项目异步文件上传功能 - 前端设计文档(轮询版本)
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
|
|
|
|
|
## 文档信息
|
|
|
|
|
|
- **创建日期**: 2026-03-05
|
2026-03-05 10:39:35 +08:00
|
|
|
|
- **版本**: v1.1
|
2026-03-05 10:10:25 +08:00
|
|
|
|
- **作者**: Claude
|
|
|
|
|
|
- **状态**: 已批准
|
|
|
|
|
|
- **关联文档**: [后端设计文档](./2026-03-05-async-file-upload-design.md)
|
2026-03-05 10:39:35 +08:00
|
|
|
|
- **变更说明**: 移除WebSocket,改为页面轮询机制
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
|
|
|
|
|
## 1. 设计概述
|
|
|
|
|
|
|
|
|
|
|
|
### 1.1 功能描述
|
2026-03-05 10:39:35 +08:00
|
|
|
|
基于现有项目管理模块的上传数据组件(UploadData.vue),扩展实现流水文件的异步批量上传功能。
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
### 1.2 技术栈
|
2026-03-05 10:10:25 +08:00
|
|
|
|
- Vue.js 2.6.12
|
|
|
|
|
|
- Element UI 2.15.14
|
|
|
|
|
|
- Axios(HTTP 请求)
|
2026-03-05 10:39:35 +08:00
|
|
|
|
- 页面轮询(定时刷新)
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
## 2. 核心变更
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
### 2.1 移除WebSocket
|
|
|
|
|
|
- 不再使用WebSocket实时推送
|
|
|
|
|
|
- 改用HTTP轮询机制定时刷新
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
### 2.2 轮询机制
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
**启动条件**:
|
|
|
|
|
|
- 上传文件后立即启动
|
|
|
|
|
|
- 检测到有uploading或parsing状态文件时自动启动
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
**停止条件**:
|
|
|
|
|
|
- 所有文件处理完成(无uploading和parsing状态)
|
|
|
|
|
|
- 组件销毁时
|
|
|
|
|
|
- 用户手动停止
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
**轮询间隔**:
|
|
|
|
|
|
- 默认5秒
|
|
|
|
|
|
- 可根据活跃任务数量动态调整
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
## 3. 轮询实现
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
### 3.1 数据结构
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
2026-03-05 10:39:35 +08:00
|
|
|
|
// 轮询相关
|
|
|
|
|
|
pollingTimer: null,
|
|
|
|
|
|
pollingEnabled: false,
|
|
|
|
|
|
pollingInterval: 5000 // 5秒
|
2026-03-05 10:10:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
### 3.2 核心方法
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
|
|
|
|
|
```javascript
|
2026-03-05 10:39:35 +08:00
|
|
|
|
methods: {
|
|
|
|
|
|
// 启动轮询
|
|
|
|
|
|
startPolling() {
|
|
|
|
|
|
if (this.pollingEnabled) return
|
|
|
|
|
|
|
|
|
|
|
|
this.pollingEnabled = true
|
|
|
|
|
|
|
|
|
|
|
|
const poll = () => {
|
|
|
|
|
|
if (!this.pollingEnabled) return
|
|
|
|
|
|
|
|
|
|
|
|
Promise.all([
|
|
|
|
|
|
this.loadStatistics(),
|
|
|
|
|
|
this.loadFileList()
|
|
|
|
|
|
]).then(() => {
|
|
|
|
|
|
// 检查是否需要继续轮询
|
|
|
|
|
|
if (this.statistics.uploading === 0 &&
|
|
|
|
|
|
this.statistics.parsing === 0) {
|
|
|
|
|
|
this.stopPolling()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.pollingTimer = setTimeout(poll, this.pollingInterval)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
poll()
|
|
|
|
|
|
},
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
// 停止轮询
|
|
|
|
|
|
stopPolling() {
|
|
|
|
|
|
this.pollingEnabled = false
|
|
|
|
|
|
if (this.pollingTimer) {
|
|
|
|
|
|
clearTimeout(this.pollingTimer)
|
|
|
|
|
|
this.pollingTimer = null
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 上传成功后启动轮询
|
|
|
|
|
|
async handleBatchUpload() {
|
|
|
|
|
|
// ... 上传逻辑 ...
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新数据并启动轮询
|
|
|
|
|
|
await Promise.all([
|
|
|
|
|
|
this.loadStatistics(),
|
|
|
|
|
|
this.loadFileList()
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
this.startPolling()
|
|
|
|
|
|
}
|
2026-03-05 10:10:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
### 3.3 生命周期管理
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
```javascript
|
|
|
|
|
|
mounted() {
|
|
|
|
|
|
this.loadStatistics()
|
|
|
|
|
|
this.loadFileList()
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否需要启动轮询
|
|
|
|
|
|
if (this.statistics.uploading > 0 || this.statistics.parsing > 0) {
|
|
|
|
|
|
this.startPolling()
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
beforeDestroy() {
|
|
|
|
|
|
this.stopPolling()
|
2026-03-05 10:10:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
## 4. 其他功能
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
批量上传弹窗、统计卡片、文件列表等功能保持不变,详见原设计文档。
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
## 5. 开发计划
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
|
|
|
|
|
1. **API 接口封装**(0.5天)
|
|
|
|
|
|
2. **批量上传弹窗**(1天)
|
|
|
|
|
|
3. **统计卡片组件**(0.5天)
|
|
|
|
|
|
4. **文件列表组件**(1天)
|
2026-03-05 10:39:35 +08:00
|
|
|
|
5. **轮询机制**(0.5天)
|
2026-03-05 10:10:25 +08:00
|
|
|
|
6. **联调测试**(1天)
|
|
|
|
|
|
|
2026-03-05 10:39:35 +08:00
|
|
|
|
**总计**:4.5个工作日
|
2026-03-05 10:10:25 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
**文档结束**
|
2026-03-05 10:39:35 +08:00
|
|
|
|
```
|