2026-02-08 13:44:13 +08:00
|
|
|
# 采购交易导入功能优化实施计划
|
|
|
|
|
|
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
|
|
|
|
|
|
|
|
**目标:** 优化采购交易管理的导入功能,采用后台异步处理+通知提示,避免弹窗阻塞用户操作,完全复用员工信息维护的导入逻辑。
|
|
|
|
|
|
|
|
|
|
**架构:** 前端Vue组件修改,使用localStorage实现状态持久化,通过轮询机制查询导入状态,使用Element UI的$notify组件显示通知。
|
|
|
|
|
|
|
|
|
|
**技术栈:** Vue 2.6.12, Element UI 2.15.14, Axios, localStorage
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 前置准备
|
|
|
|
|
|
|
|
|
|
### Task 0: 验证参考代码存在
|
|
|
|
|
|
|
|
|
|
**目标:** 确认员工信息维护的导入功能代码存在,作为参考
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- 参考: `ruoyi-ui/src/views/ccdiEmployee/index.vue`
|
|
|
|
|
- 修改: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 检查参考文件是否存在**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
test -f ruoyi-ui/src/views/ccdiEmployee/index.vue && echo "参考文件存在" || echo "参考文件不存在"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: "参考文件存在"
|
|
|
|
|
|
|
|
|
|
**Step 2: 检查目标文件是否存在**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
test -f ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue && echo "目标文件存在" || echo "目标文件不存在"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: "目标文件存在"
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第一阶段:添加data属性
|
|
|
|
|
|
|
|
|
|
### Task 1: 添加导入轮询相关属性
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 定位data()函数中的upload对象**
|
|
|
|
|
|
|
|
|
|
在文件中查找 `// 导入参数` 注释,找到upload对象定义的位置。
|
|
|
|
|
|
|
|
|
|
**Step 2: 在upload对象之后添加轮询相关属性**
|
|
|
|
|
|
|
|
|
|
在 `upload: {...}` 对象之后,添加以下代码:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
// 导入轮询定时器
|
|
|
|
|
importPollingTimer: null,
|
|
|
|
|
// 是否显示查看失败记录按钮
|
|
|
|
|
showFailureButton: false,
|
|
|
|
|
// 当前导入任务ID
|
|
|
|
|
currentTaskId: null,
|
|
|
|
|
// 失败记录对话框
|
|
|
|
|
failureDialogVisible: false,
|
|
|
|
|
failureList: [],
|
|
|
|
|
failureLoading: false,
|
|
|
|
|
failureTotal: 0,
|
|
|
|
|
failureQueryParams: {
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
pageSize: 10
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 3: 保存文件并验证语法**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
cd ruoyi-ui && npm run build:prod -- --no-clean 2>&1 | head -20
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: 没有语法错误
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加导入轮询相关data属性
|
|
|
|
|
|
|
|
|
|
- 添加importPollingTimer定时器
|
|
|
|
|
- 添加showFailureButton失败记录按钮显示状态
|
|
|
|
|
- 添加currentTaskId当前任务ID
|
|
|
|
|
- 添加失败记录对话框相关属性(failureDialogVisible等)
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第二阶段:添加computed属性
|
|
|
|
|
|
|
|
|
|
### Task 2: 添加lastImportInfo计算属性
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 定位computed部分**
|
|
|
|
|
|
|
|
|
|
在文件中查找 `computed:` 或找到data()函数结束的位置。
|
|
|
|
|
|
|
|
|
|
**Step 2: 添加computed属性**
|
|
|
|
|
|
|
|
|
|
如果已有computed对象,在其中添加;如果没有,在data()之后创建computed对象:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
computed: {
|
|
|
|
|
/**
|
|
|
|
|
* 上次导入信息摘要
|
|
|
|
|
*/
|
|
|
|
|
lastImportInfo() {
|
|
|
|
|
const savedTask = this.getImportTaskFromStorage();
|
|
|
|
|
if (savedTask && savedTask.totalCount) {
|
|
|
|
|
return `导入时间: ${this.parseTime(savedTask.saveTime)} | 总数: ${savedTask.totalCount}条 | 成功: ${savedTask.successCount}条 | 失败: ${savedTask.failureCount}条`;
|
|
|
|
|
}
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 3: 保存文件并验证语法**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
cd ruoyi-ui && npm run build:prod -- --no-clean 2>&1 | head -20
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: 没有语法错误
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加lastImportInfo计算属性
|
|
|
|
|
|
|
|
|
|
- 显示上次导入的信息摘要
|
|
|
|
|
- 包含导入时间、总数、成功数、失败数
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第三阶段:修改生命周期钩子
|
|
|
|
|
|
|
|
|
|
### Task 3: 修改created钩子
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 定位created()钩子**
|
|
|
|
|
|
|
|
|
|
查找 `created() {` 或 `created() {` 在文件中的位置。
|
|
|
|
|
|
|
|
|
|
**Step 2: 在created()中添加restoreImportState调用**
|
|
|
|
|
|
|
|
|
|
在 `this.getList();` 之后添加:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
this.restoreImportState(); // 恢复导入状态
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 3: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 在created钩子中恢复导入状态
|
|
|
|
|
|
|
|
|
|
- 页面加载时从localStorage恢复导入状态
|
|
|
|
|
- 如果有失败记录则显示查看按钮
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 4: 修改beforeDestroy钩子
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 定位beforeDestroy()钩子**
|
|
|
|
|
|
|
|
|
|
查找 `beforeDestroy() {` 在文件中的位置。
|
|
|
|
|
|
|
|
|
|
**Step 2: 添加定时器清理代码**
|
|
|
|
|
|
|
|
|
|
在beforeDestroy()中添加:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
// 清理定时器
|
|
|
|
|
if (this.importPollingTimer) {
|
|
|
|
|
clearInterval(this.importPollingTimer);
|
|
|
|
|
this.importPollingTimer = null;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
如果beforeDestroy()不存在,在created()之后创建它。
|
|
|
|
|
|
|
|
|
|
**Step 3: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 在beforeDestroy钩子中清理定时器
|
|
|
|
|
|
|
|
|
|
- 防止内存泄漏
|
|
|
|
|
- 组件销毁时清除轮询定时器
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第四阶段:添加localStorage管理方法
|
|
|
|
|
|
|
|
|
|
### Task 5: 添加saveImportTaskToStorage方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 定位methods部分**
|
|
|
|
|
|
|
|
|
|
查找 `methods: {` 在文件中的位置。
|
|
|
|
|
|
|
|
|
|
**Step 2: 在methods中添加saveImportTaskToStorage方法**
|
|
|
|
|
|
|
|
|
|
在methods对象的适当位置添加:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/**
|
|
|
|
|
* 保存导入任务到localStorage
|
|
|
|
|
* @param {Object} taskData - 任务数据
|
|
|
|
|
*/
|
|
|
|
|
saveImportTaskToStorage(taskData) {
|
|
|
|
|
try {
|
|
|
|
|
const data = {
|
|
|
|
|
...taskData,
|
|
|
|
|
saveTime: Date.now()
|
|
|
|
|
};
|
|
|
|
|
localStorage.setItem('purchase_transaction_import_last_task', JSON.stringify(data));
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('保存导入任务状态失败:', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 3: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加saveImportTaskToStorage方法
|
|
|
|
|
|
|
|
|
|
- 保存导入任务状态到localStorage
|
|
|
|
|
- 存储key: purchase_transaction_import_last_task
|
|
|
|
|
- 自动添加时间戳
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 6: 添加getImportTaskFromStorage方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在saveImportTaskToStorage之后添加方法**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/**
|
|
|
|
|
* 从localStorage读取导入任务
|
|
|
|
|
* @returns {Object|null} 任务数据或null
|
|
|
|
|
*/
|
|
|
|
|
getImportTaskFromStorage() {
|
|
|
|
|
try {
|
|
|
|
|
const data = localStorage.getItem('purchase_transaction_import_last_task');
|
|
|
|
|
if (!data) return null;
|
|
|
|
|
|
|
|
|
|
const task = JSON.parse(data);
|
|
|
|
|
|
|
|
|
|
// 数据格式校验
|
|
|
|
|
if (!task || !task.taskId) {
|
|
|
|
|
this.clearImportTaskFromStorage();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 时间戳校验
|
|
|
|
|
if (task.saveTime && typeof task.saveTime !== 'number') {
|
|
|
|
|
this.clearImportTaskFromStorage();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 过期检查(7天)
|
|
|
|
|
const sevenDays = 7 * 24 * 60 * 60 * 1000;
|
|
|
|
|
if (Date.now() - task.saveTime > sevenDays) {
|
|
|
|
|
this.clearImportTaskFromStorage();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return task;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('读取导入任务状态失败:', error);
|
|
|
|
|
this.clearImportTaskFromStorage();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加getImportTaskFromStorage方法
|
|
|
|
|
|
|
|
|
|
- 从localStorage读取导入任务状态
|
|
|
|
|
- 包含数据格式校验
|
|
|
|
|
- 包含7天过期检查
|
|
|
|
|
- 异常时自动清除无效数据
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 7: 添加clearImportTaskFromStorage方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在getImportTaskFromStorage之后添加方法**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/**
|
|
|
|
|
* 清除localStorage中的导入任务
|
|
|
|
|
*/
|
|
|
|
|
clearImportTaskFromStorage() {
|
|
|
|
|
try {
|
|
|
|
|
localStorage.removeItem('purchase_transaction_import_last_task');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('清除导入任务状态失败:', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加clearImportTaskFromStorage方法
|
|
|
|
|
|
|
|
|
|
- 清除localStorage中的导入任务状态
|
|
|
|
|
- 异常处理防止报错
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第五阶段:添加状态恢复和提示方法
|
|
|
|
|
|
|
|
|
|
### Task 8: 添加restoreImportState方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在clearImportTaskFromStorage之后添加方法**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/**
|
|
|
|
|
* 恢复导入状态
|
|
|
|
|
* 在created()钩子中调用
|
|
|
|
|
*/
|
|
|
|
|
restoreImportState() {
|
|
|
|
|
const savedTask = this.getImportTaskFromStorage();
|
|
|
|
|
|
|
|
|
|
if (!savedTask) {
|
|
|
|
|
this.showFailureButton = false;
|
|
|
|
|
this.currentTaskId = null;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果有失败记录,恢复按钮显示
|
|
|
|
|
if (savedTask.hasFailures && savedTask.taskId) {
|
|
|
|
|
this.currentTaskId = savedTask.taskId;
|
|
|
|
|
this.showFailureButton = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加restoreImportState方法
|
|
|
|
|
|
|
|
|
|
- 页面加载时恢复导入状态
|
|
|
|
|
- 如果有失败记录则显示查看按钮
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 9: 添加getLastImportTooltip方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在restoreImportState之后添加方法**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/**
|
|
|
|
|
* 获取上次导入的提示信息
|
|
|
|
|
* @returns {String} 提示文本
|
|
|
|
|
*/
|
|
|
|
|
getLastImportTooltip() {
|
|
|
|
|
const savedTask = this.getImportTaskFromStorage();
|
|
|
|
|
if (savedTask && savedTask.saveTime) {
|
|
|
|
|
const date = new Date(savedTask.saveTime);
|
|
|
|
|
const timeStr = this.parseTime(date, '{y}-{m}-{d} {h}:{i}');
|
|
|
|
|
return `上次导入: ${timeStr}`;
|
|
|
|
|
}
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加getLastImportTooltip方法
|
|
|
|
|
|
|
|
|
|
- 获取上次导入的提示信息
|
|
|
|
|
- 用于tooltip显示
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第六阶段:修改导入上传逻辑
|
|
|
|
|
|
|
|
|
|
### Task 10: 修改handleFileSuccess方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 定位handleFileSuccess方法**
|
|
|
|
|
|
|
|
|
|
查找 `handleFileSuccess(response, file, fileList)` 方法。
|
|
|
|
|
|
|
|
|
|
**Step 2: 完全替换方法实现**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
// 文件上传成功处理
|
|
|
|
|
handleFileSuccess(response, file, fileList) {
|
|
|
|
|
this.upload.isUploading = false;
|
|
|
|
|
this.upload.open = false;
|
|
|
|
|
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
// 验证响应数据完整性
|
|
|
|
|
if (!response.data || !response.data.taskId) {
|
|
|
|
|
this.$modal.msgError('导入任务创建失败:缺少任务ID');
|
|
|
|
|
this.upload.isUploading = false;
|
|
|
|
|
this.upload.open = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const taskId = response.data.taskId;
|
|
|
|
|
|
|
|
|
|
// 清除旧的轮询定时器
|
|
|
|
|
if (this.importPollingTimer) {
|
|
|
|
|
clearInterval(this.importPollingTimer);
|
|
|
|
|
this.importPollingTimer = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.clearImportTaskFromStorage();
|
|
|
|
|
|
|
|
|
|
// 保存新任务的初始状态
|
|
|
|
|
this.saveImportTaskToStorage({
|
|
|
|
|
taskId: taskId,
|
|
|
|
|
status: 'PROCESSING',
|
|
|
|
|
timestamp: Date.now(),
|
|
|
|
|
hasFailures: false
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 重置状态
|
|
|
|
|
this.showFailureButton = false;
|
|
|
|
|
this.currentTaskId = taskId;
|
|
|
|
|
|
|
|
|
|
// 显示后台处理提示(不是弹窗,是通知)
|
|
|
|
|
this.$notify({
|
|
|
|
|
title: '导入任务已提交',
|
|
|
|
|
message: '正在后台处理中,处理完成后将通知您',
|
|
|
|
|
type: 'info',
|
|
|
|
|
duration: 3000
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 开始轮询检查状态
|
|
|
|
|
this.startImportStatusPolling(taskId);
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError(response.msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 3: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 修改handleFileSuccess为异步处理
|
|
|
|
|
|
|
|
|
|
- 上传成功后立即关闭对话框
|
|
|
|
|
- 使用通知替代弹窗提示
|
|
|
|
|
- 开始轮询导入状态
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第七阶段:添加轮询和完成处理方法
|
|
|
|
|
|
|
|
|
|
### Task 11: 添加startImportStatusPolling方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在handleFileSuccess之后添加方法**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/** 开始轮询导入状态 */
|
|
|
|
|
startImportStatusPolling(taskId) {
|
|
|
|
|
let pollCount = 0;
|
|
|
|
|
const maxPolls = 150; // 最多轮询150次(5分钟)
|
|
|
|
|
|
|
|
|
|
this.importPollingTimer = setInterval(async () => {
|
|
|
|
|
try {
|
|
|
|
|
pollCount++;
|
|
|
|
|
|
|
|
|
|
// 超时检查
|
|
|
|
|
if (pollCount > maxPolls) {
|
|
|
|
|
clearInterval(this.importPollingTimer);
|
|
|
|
|
this.$modal.msgWarning('导入任务处理超时,请联系管理员');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const response = await getImportStatus(taskId);
|
|
|
|
|
|
|
|
|
|
if (response.data && response.data.status !== 'PROCESSING') {
|
|
|
|
|
clearInterval(this.importPollingTimer);
|
|
|
|
|
this.handleImportComplete(response.data);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
clearInterval(this.importPollingTimer);
|
|
|
|
|
this.$modal.msgError('查询导入状态失败: ' + error.message);
|
|
|
|
|
}
|
|
|
|
|
}, 2000); // 每2秒轮询一次
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加startImportStatusPolling方法
|
|
|
|
|
|
|
|
|
|
- 每2秒轮询一次导入状态
|
|
|
|
|
- 最多轮询150次(5分钟)
|
|
|
|
|
- 超时后显示警告
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 12: 添加handleImportComplete方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在startImportStatusPolling之后添加方法**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/** 处理导入完成 */
|
|
|
|
|
handleImportComplete(statusResult) {
|
|
|
|
|
// 更新localStorage中的任务状态
|
|
|
|
|
this.saveImportTaskToStorage({
|
|
|
|
|
taskId: statusResult.taskId,
|
|
|
|
|
status: statusResult.status,
|
|
|
|
|
hasFailures: statusResult.failureCount > 0,
|
|
|
|
|
totalCount: statusResult.totalCount,
|
|
|
|
|
successCount: statusResult.successCount,
|
|
|
|
|
failureCount: statusResult.failureCount
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (statusResult.status === 'SUCCESS') {
|
|
|
|
|
// 全部成功
|
|
|
|
|
this.$notify({
|
|
|
|
|
title: '导入完成',
|
|
|
|
|
message: `全部成功!共导入${statusResult.totalCount}条数据`,
|
|
|
|
|
type: 'success',
|
|
|
|
|
duration: 5000
|
|
|
|
|
});
|
|
|
|
|
this.showFailureButton = false; // 成功时清除失败按钮显示
|
|
|
|
|
this.getList();
|
|
|
|
|
} else if (statusResult.failureCount > 0) {
|
|
|
|
|
// 部分失败
|
|
|
|
|
this.$notify({
|
|
|
|
|
title: '导入完成',
|
|
|
|
|
message: `成功${statusResult.successCount}条,失败${statusResult.failureCount}条`,
|
|
|
|
|
type: 'warning',
|
|
|
|
|
duration: 5000
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 显示查看失败记录按钮
|
|
|
|
|
this.showFailureButton = true;
|
|
|
|
|
this.currentTaskId = statusResult.taskId;
|
|
|
|
|
|
|
|
|
|
// 刷新列表
|
|
|
|
|
this.getList();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加handleImportComplete方法
|
|
|
|
|
|
|
|
|
|
- 处理导入完成逻辑
|
|
|
|
|
- 全部成功时显示成功通知
|
|
|
|
|
- 部分失败时显示警告通知和失败记录按钮
|
|
|
|
|
- 自动刷新列表
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第八阶段:添加失败记录查看方法
|
|
|
|
|
|
|
|
|
|
### Task 13: 添加viewImportFailures方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在handleImportComplete之后添加方法**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/** 查看导入失败记录 */
|
|
|
|
|
viewImportFailures() {
|
|
|
|
|
this.failureDialogVisible = true;
|
|
|
|
|
this.getFailureList();
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加viewImportFailures方法
|
|
|
|
|
|
|
|
|
|
- 打开失败记录对话框
|
|
|
|
|
- 加载失败记录列表
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 14: 添加getFailureList方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在viewImportFailures之后添加方法**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/** 查询失败记录列表 */
|
|
|
|
|
getFailureList() {
|
|
|
|
|
this.failureLoading = true;
|
|
|
|
|
getImportFailures(
|
|
|
|
|
this.currentTaskId,
|
|
|
|
|
this.failureQueryParams.pageNum,
|
|
|
|
|
this.failureQueryParams.pageSize
|
|
|
|
|
).then(response => {
|
|
|
|
|
this.failureList = response.rows;
|
|
|
|
|
this.failureTotal = response.total;
|
|
|
|
|
this.failureLoading = false;
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
this.failureLoading = false;
|
|
|
|
|
|
|
|
|
|
// 处理不同类型的错误
|
|
|
|
|
if (error.response) {
|
|
|
|
|
const status = error.response.status;
|
|
|
|
|
|
|
|
|
|
if (status === 404) {
|
|
|
|
|
// 记录不存在或已过期
|
|
|
|
|
this.$modal.msgWarning('导入记录已过期,无法查看失败记录');
|
|
|
|
|
this.clearImportTaskFromStorage();
|
|
|
|
|
this.showFailureButton = false;
|
|
|
|
|
this.currentTaskId = null;
|
|
|
|
|
this.failureDialogVisible = false;
|
|
|
|
|
} else if (status === 500) {
|
|
|
|
|
this.$modal.msgError('服务器错误,请稍后重试');
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError(`查询失败: ${error.response.data.msg || '未知错误'}`);
|
|
|
|
|
}
|
|
|
|
|
} else if (error.request) {
|
|
|
|
|
// 请求发送了但没有收到响应
|
|
|
|
|
this.$modal.msgError('网络连接失败,请检查网络');
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError('查询失败记录失败: ' + error.message);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加getFailureList方法
|
|
|
|
|
|
|
|
|
|
- 查询分页的失败记录列表
|
|
|
|
|
- 完善的错误处理(404/500/网络错误等)
|
|
|
|
|
- 记录过期时自动清除状态
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 15: 添加clearImportHistory方法
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在getFailureList之后添加方法**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
/**
|
|
|
|
|
* 清除导入历史记录
|
|
|
|
|
* 用户手动触发
|
|
|
|
|
*/
|
|
|
|
|
clearImportHistory() {
|
|
|
|
|
this.$confirm('确认清除上次导入记录?', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
type: 'warning'
|
|
|
|
|
}).then(() => {
|
|
|
|
|
this.clearImportTaskFromStorage();
|
|
|
|
|
this.showFailureButton = false;
|
|
|
|
|
this.currentTaskId = null;
|
|
|
|
|
this.failureDialogVisible = false;
|
|
|
|
|
this.$message.success('已清除');
|
|
|
|
|
}).catch(() => {});
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加clearImportHistory方法
|
|
|
|
|
|
|
|
|
|
- 清除localStorage中的导入历史
|
|
|
|
|
- 隐藏查看失败记录按钮
|
|
|
|
|
- 需要用户确认
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第九阶段:修改UI组件
|
|
|
|
|
|
|
|
|
|
### Task 16: 修改导入对话框(移除loading)
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 定位导入对话框**
|
|
|
|
|
|
|
|
|
|
查找 `<el-dialog` 包含 `upload.title` 的位置。
|
|
|
|
|
|
|
|
|
|
**Step 2: 移除loading相关属性**
|
|
|
|
|
|
|
|
|
|
从el-dialog标签中移除以下属性:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- `v-loading="upload.isUploading"`
|
|
|
|
|
- `element-loading-text="正在导入数据,请稍候..."`
|
|
|
|
|
- `element-loading-spinner="el-icon-loading"`
|
|
|
|
|
- `element-loading-background="rgba(0, 0, 0, 0.7)"`
|
|
|
|
|
|
|
|
|
|
修改后的el-dialog应该类似:
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
<el-dialog
|
|
|
|
|
:title="upload.title"
|
|
|
|
|
:visible.sync="upload.open"
|
|
|
|
|
width="400px"
|
|
|
|
|
append-to-body
|
|
|
|
|
@close="handleImportDialogClose"
|
|
|
|
|
>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 3: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "refactor: 移除导入对话框的loading属性
|
|
|
|
|
|
|
|
|
|
- 导入改为后台异步处理,不需要显示loading
|
|
|
|
|
- 提升用户体验
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 17: 添加"查看导入失败记录"按钮
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 定位操作栏的导入按钮和导出按钮**
|
|
|
|
|
|
|
|
|
|
查找包含 `@click="handleImport"` 和 `@click="handleExport"` 的el-col。
|
|
|
|
|
|
|
|
|
|
**Step 2: 在导出按钮之后添加查看失败记录按钮**
|
|
|
|
|
|
|
|
|
|
在导出按钮的 `</el-col>` 之后添加:
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
<el-col :span="1.5" v-if="showFailureButton">
|
|
|
|
|
<el-tooltip
|
|
|
|
|
:content="getLastImportTooltip()"
|
|
|
|
|
placement="top"
|
|
|
|
|
>
|
|
|
|
|
<el-button
|
|
|
|
|
type="warning"
|
|
|
|
|
plain
|
|
|
|
|
icon="el-icon-warning"
|
|
|
|
|
size="mini"
|
|
|
|
|
@click="viewImportFailures"
|
|
|
|
|
>查看导入失败记录</el-button>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
</el-col>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 3: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加查看导入失败记录按钮
|
|
|
|
|
|
|
|
|
|
- 仅在有失败记录时显示
|
|
|
|
|
- 带tooltip显示上次导入信息
|
|
|
|
|
- 点击打开失败记录对话框
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 18: 添加导入失败记录对话框
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 定位导入结果对话框**
|
|
|
|
|
|
|
|
|
|
查找 `<import-result-dialog` 组件。
|
|
|
|
|
|
|
|
|
|
**Step 2: 在导入结果对话框之后添加失败记录对话框**
|
|
|
|
|
|
|
|
|
|
在 `</import-result-dialog>` 之后添加:
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
<!-- 导入失败记录对话框 -->
|
|
|
|
|
<el-dialog
|
|
|
|
|
title="导入失败记录"
|
|
|
|
|
:visible.sync="failureDialogVisible"
|
|
|
|
|
width="1200px"
|
|
|
|
|
append-to-body
|
|
|
|
|
>
|
|
|
|
|
<el-alert
|
|
|
|
|
v-if="lastImportInfo"
|
|
|
|
|
:title="lastImportInfo"
|
|
|
|
|
type="info"
|
|
|
|
|
:closable="false"
|
|
|
|
|
style="margin-bottom: 15px"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<el-table :data="failureList" v-loading="failureLoading">
|
|
|
|
|
<el-table-column label="采购事项ID" prop="purchaseId" align="center" />
|
|
|
|
|
<el-table-column label="项目名称" prop="projectName" align="center" :show-overflow-tooltip="true"/>
|
|
|
|
|
<el-table-column label="标的物名称" prop="subjectName" align="center" :show-overflow-tooltip="true"/>
|
|
|
|
|
<el-table-column label="失败原因" prop="errorMessage" align="center" min-width="200" :show-overflow-tooltip="true" />
|
|
|
|
|
</el-table>
|
|
|
|
|
|
|
|
|
|
<pagination
|
|
|
|
|
v-show="failureTotal > 0"
|
|
|
|
|
:total="failureTotal"
|
|
|
|
|
:page.sync="failureQueryParams.pageNum"
|
|
|
|
|
:limit.sync="failureQueryParams.pageSize"
|
|
|
|
|
@pagination="getFailureList"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<div slot="footer" class="dialog-footer">
|
|
|
|
|
<el-button @click="failureDialogVisible = false">关闭</el-button>
|
|
|
|
|
<el-button type="danger" plain @click="clearImportHistory">清除历史记录</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 3: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue
|
|
|
|
|
git commit -m "feat: 添加导入失败记录对话框
|
|
|
|
|
|
|
|
|
|
- 显示导入信息摘要
|
|
|
|
|
- 分页显示失败记录(采购事项ID、项目名称、标的物名称、失败原因)
|
|
|
|
|
- 支持清除历史记录
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第十阶段:验证和测试
|
|
|
|
|
|
|
|
|
|
### Task 19: 语法验证
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Verify: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
|
|
|
|
|
**Step 1: 检查Vue文件语法**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
cd ruoyi-ui && npm run build:prod -- --no-clean 2>&1 | grep -A 5 "ccdiPurchaseTransaction/index.vue" | head -20
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: 没有语法错误
|
|
|
|
|
|
|
|
|
|
**Step 2: 检查是否有未定义的变量**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
cd ruoyi-ui && npm run build:prod -- --no-clean 2>&1 | grep -i "undefined" | head -10
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: 没有相关错误
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交验证通过说明**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git commit --allow-empty -m "test: 语法验证通过
|
|
|
|
|
|
|
|
|
|
- Vue文件语法检查通过
|
|
|
|
|
- 无未定义变量
|
|
|
|
|
- 所有方法已正确添加
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 20: 功能测试准备
|
|
|
|
|
|
|
|
|
|
**目标:** 准备测试数据和测试场景
|
|
|
|
|
|
|
|
|
|
**Step 1: 确认测试数据文件存在**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
ls -lh doc/test-data/purchase_transaction/*.xlsx
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: 显示至少一个xlsx文件
|
|
|
|
|
|
|
|
|
|
**Step 2: 确认API接口可用**
|
|
|
|
|
|
|
|
|
|
检查后端服务是否运行:
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
curl -s http://localhost:8080/swagger-ui/index.html | grep -o "purchaseTransaction" | head -1
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: 输出"purchaseTransaction"
|
|
|
|
|
|
|
|
|
|
**Step 3: 记录测试环境信息**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
cat > doc/test-data/purchase_transaction/TEST_ENV.md << 'EOF'
|
|
|
|
|
# 测试环境信息
|
|
|
|
|
|
|
|
|
|
## 测试日期
|
|
|
|
|
$(date +%Y-%m-%d)
|
|
|
|
|
|
|
|
|
|
## 后端服务
|
|
|
|
|
- URL: http://localhost:8080
|
|
|
|
|
- Swagger: http://localhost:8080/swagger-ui/index.html
|
|
|
|
|
|
|
|
|
|
## 测试账号
|
|
|
|
|
- username: admin
|
|
|
|
|
- password: admin123
|
|
|
|
|
|
|
|
|
|
## 测试接口
|
|
|
|
|
1. 导入: POST /ccdi/purchaseTransaction/importData
|
|
|
|
|
2. 查询状态: GET /ccdi/purchaseTransaction/importStatus/{taskId}
|
|
|
|
|
3. 查询失败记录: GET /ccdi/purchaseTransaction/importFailures/{taskId}
|
|
|
|
|
|
|
|
|
|
## 测试数据文件
|
|
|
|
|
- purchase_test_data_2000.xlsx (2000条测试数据)
|
|
|
|
|
EOF
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 4: 提交测试准备文档**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add doc/test-data/purchase_transaction/TEST_ENV.md
|
|
|
|
|
git commit -m "test: 添加测试环境信息文档
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 21: 创建测试脚本
|
|
|
|
|
|
|
|
|
|
**目标:** 创建自动化测试脚本
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Create: `doc/test-data/purchase_transaction/test-import-flow.js`
|
|
|
|
|
|
|
|
|
|
**Step 1: 创建测试脚本**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
|
|
|
|
// 测试配置
|
|
|
|
|
const CONFIG = {
|
|
|
|
|
baseUrl: 'http://localhost:8080',
|
|
|
|
|
username: 'admin',
|
|
|
|
|
password: 'admin123',
|
|
|
|
|
testFile: path.join(__dirname, 'purchase_test_data_2000.xlsx')
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 日志函数
|
|
|
|
|
function log(message, level = 'INFO') {
|
|
|
|
|
const timestamp = new Date().toISOString();
|
|
|
|
|
console.log(`[${timestamp}] [${level}] ${message}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 测试步骤清单
|
|
|
|
|
const TEST_STEPS = [
|
|
|
|
|
{
|
|
|
|
|
name: '1. 登录获取token',
|
|
|
|
|
action: async () => {
|
|
|
|
|
// TODO: 实现登录逻辑
|
|
|
|
|
log('登录功能需要手动实现或使用curl命令');
|
|
|
|
|
return 'mock-token-xxx';
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '2. 上传测试文件',
|
|
|
|
|
action: async (token) => {
|
|
|
|
|
log('上传文件:', CONFIG.testFile);
|
|
|
|
|
// TODO: 实现文件上传
|
|
|
|
|
return { taskId: 'mock-task-id' };
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '3. 等待导入完成',
|
|
|
|
|
action: async (taskId) => {
|
|
|
|
|
log('等待任务完成:', taskId);
|
|
|
|
|
log('请手动查看右上角通知');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '4. 验证结果',
|
|
|
|
|
action: async () => {
|
|
|
|
|
log('验证:');
|
|
|
|
|
log(' - 对话框已关闭 ✓');
|
|
|
|
|
log(' - 显示导入通知 ✓');
|
|
|
|
|
log(' - 如有失败,显示查看失败记录按钮 ✓');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 主测试流程
|
|
|
|
|
async function runTests() {
|
|
|
|
|
log('=== 采购交易导入功能测试 ===');
|
|
|
|
|
log('开始时间:', new Date().toLocaleString('zh-CN'));
|
|
|
|
|
|
|
|
|
|
for (const step of TEST_STEPS) {
|
|
|
|
|
log(`\n执行: ${step.name}`);
|
|
|
|
|
try {
|
|
|
|
|
await step.action();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
log(`失败: ${error.message}`, 'ERROR');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log('\n=== 测试完成 ===');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 导出测试函数
|
|
|
|
|
module.exports = { runTests, TEST_STEPS };
|
|
|
|
|
|
|
|
|
|
// 如果直接运行此脚本
|
|
|
|
|
if (require.main === module) {
|
|
|
|
|
runTests();
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add doc/test-data/purchase_transaction/test-import-flow.js
|
|
|
|
|
git commit -m "test: 添加导入功能测试脚本
|
|
|
|
|
|
|
|
|
|
- 测试流程框架
|
|
|
|
|
- 包含主要测试步骤
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 第十一阶段:文档更新
|
|
|
|
|
|
|
|
|
|
### Task 22: 更新API文档
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Modify: `doc/api/ccdi_purchase_transaction_api.md`
|
|
|
|
|
|
|
|
|
|
**Step 1: 在文档末尾添加导入交互说明**
|
|
|
|
|
|
|
|
|
|
```markdown
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 导入功能交互说明
|
|
|
|
|
|
|
|
|
|
### 前端交互流程
|
|
|
|
|
|
|
|
|
|
1. **上传文件**
|
|
|
|
|
- 用户点击"导入"按钮
|
|
|
|
|
- 选择Excel文件
|
|
|
|
|
- 点击"确定"上传
|
|
|
|
|
- **导入对话框立即关闭**
|
|
|
|
|
|
|
|
|
|
2. **后台处理**
|
|
|
|
|
- 右上角显示通知:"导入任务已提交,正在后台处理中,处理完成后将通知您"
|
|
|
|
|
- 系统每2秒轮询一次导入状态
|
|
|
|
|
|
|
|
|
|
3. **导入完成**
|
|
|
|
|
- 全部成功:显示绿色通知"导入完成!全部成功!共导入N条数据"
|
|
|
|
|
- 部分失败:显示橙色通知"导入完成!成功N条,失败M条"
|
|
|
|
|
- 如果有失败记录,操作栏显示"查看导入失败记录"按钮
|
|
|
|
|
|
|
|
|
|
4. **查看失败记录**
|
|
|
|
|
- 点击"查看导入失败记录"按钮
|
|
|
|
|
- 打开对话框显示分页的失败记录
|
|
|
|
|
- 包含字段:采购事项ID、项目名称、标的物名称、失败原因
|
|
|
|
|
- 支持清除历史记录
|
|
|
|
|
|
|
|
|
|
### 状态持久化
|
|
|
|
|
|
|
|
|
|
- 导入状态保存在localStorage中
|
|
|
|
|
- 刷新页面后仍可查看上次导入结果
|
|
|
|
|
- 状态保留7天,过期自动清除
|
|
|
|
|
|
|
|
|
|
### 与员工信息导入的对比
|
|
|
|
|
|
|
|
|
|
采购交易导入完全复用了员工信息导入的逻辑,两者的交互方式完全一致。
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add doc/api/ccdi_purchase_transaction_api.md
|
|
|
|
|
git commit -m "docs: 更新API文档,添加导入交互说明
|
|
|
|
|
|
|
|
|
|
- 详细的前端交互流程
|
|
|
|
|
- 状态持久化说明
|
|
|
|
|
- 与员工信息导入的对比
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 23: 创建变更日志
|
|
|
|
|
|
|
|
|
|
**Files:**
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Create: `doc/plans/2026-02-08-purchase-transaction-import-changelog.md`
|
|
|
|
|
|
|
|
|
|
**Step 1: 创建变更日志文档**
|
|
|
|
|
|
|
|
|
|
```markdown
|
|
|
|
|
# 采购交易导入功能优化 - 变更日志
|
|
|
|
|
|
|
|
|
|
## 变更概述
|
|
|
|
|
- **日期**: 2026-02-08
|
|
|
|
|
- **类型**: 功能优化
|
|
|
|
|
- **影响范围**: 前端UI组件
|
|
|
|
|
- **向后兼容**: 是
|
|
|
|
|
|
|
|
|
|
## 变更内容
|
|
|
|
|
|
|
|
|
|
### 用户体验改进
|
|
|
|
|
- ✅ 导入对话框不再阻塞,上传后立即关闭
|
|
|
|
|
- ✅ 使用右上角通知替代弹窗提示
|
|
|
|
|
- ✅ 支持后台异步导入,用户可继续操作
|
|
|
|
|
- ✅ 导入完成后自动刷新列表
|
|
|
|
|
|
|
|
|
|
### 新增功能
|
|
|
|
|
- ✅ 查看导入失败记录功能
|
|
|
|
|
- ✅ 导入状态持久化(7天)
|
|
|
|
|
- ✅ 分页查看失败记录
|
|
|
|
|
- ✅ 清除导入历史功能
|
|
|
|
|
|
|
|
|
|
### 技术改进
|
|
|
|
|
- ✅ 使用localStorage保存导入状态
|
|
|
|
|
- ✅ 轮询机制查询导入状态(2秒间隔,5分钟超时)
|
|
|
|
|
- ✅ 完善的错误处理(404/500/网络错误)
|
|
|
|
|
|
|
|
|
|
## 文件变更
|
|
|
|
|
|
|
|
|
|
### 修改文件
|
|
|
|
|
- `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
|
|
|
|
|
- 新增10个data属性
|
|
|
|
|
- 新增1个computed属性
|
|
|
|
|
- 新增11个方法
|
|
|
|
|
- 修改1个方法(handleFileSuccess)
|
|
|
|
|
- 修改2个生命周期钩子
|
|
|
|
|
- 新增1个UI对话框
|
|
|
|
|
|
|
|
|
|
### 新增文件
|
|
|
|
|
- `doc/test-data/purchase_transaction/test-import-flow.js` - 测试脚本
|
|
|
|
|
|
|
|
|
|
## 测试清单
|
|
|
|
|
|
|
|
|
|
- [ ] 正常导入流程测试
|
|
|
|
|
- [ ] 全部成功场景测试
|
|
|
|
|
- [ ] 部分失败场景测试
|
|
|
|
|
- [ ] 失败记录查看测试
|
|
|
|
|
- [ ] 状态持久化测试
|
|
|
|
|
- [ ] 清除历史记录测试
|
|
|
|
|
- [ ] 边界情况测试(超时、过期、网络错误)
|
|
|
|
|
|
|
|
|
|
## 部署说明
|
|
|
|
|
|
|
|
|
|
### 前端部署
|
|
|
|
|
```bash
|
|
|
|
|
cd ruoyi-ui
|
|
|
|
|
npm run build:prod
|
|
|
|
|
# 将dist目录部署到Web服务器
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 环境要求
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- Node.js 14+
|
|
|
|
|
- 现代浏览器(Chrome/Firefox/Edge)
|
|
|
|
|
|
|
|
|
|
## 回滚方案
|
|
|
|
|
|
|
|
|
|
如需回滚,恢复以下commit之前的状态:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
git revert <commit-hash>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 相关文档
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- 设计文档: `doc/plans/2026-02-08-purchase-transaction-import-design.md`
|
|
|
|
|
- API文档: `doc/api/ccdi_purchase_transaction_api.md`
|
|
|
|
|
- 实施计划: `doc/plans/2026-02-08-purchase-transaction-import-implementation.md`
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 2: 保存文件**
|
|
|
|
|
|
|
|
|
|
**Step 3: 提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add doc/plans/2026-02-08-purchase-transaction-import-changelog.md
|
|
|
|
|
git commit -m "docs: 添加变更日志
|
|
|
|
|
|
|
|
|
|
- 变更概述和影响范围
|
|
|
|
|
- 文件变更清单
|
|
|
|
|
- 测试清单和部署说明
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 完成检查清单
|
|
|
|
|
|
|
|
|
|
### Task 24: 最终验证和提交
|
|
|
|
|
|
|
|
|
|
**目标:** 确保所有任务完成,准备合并
|
|
|
|
|
|
|
|
|
|
**Step 1: 检查所有方法是否已添加**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
grep -E "(saveImportTaskToStorage|getImportTaskFromStorage|clearImportTaskFromStorage|restoreImportState|getLastImportTooltip|startImportStatusPolling|handleImportComplete|viewImportFailures|getFailureList|clearImportHistory)" ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue | wc -l
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: 输出应该大于等于10(每个方法至少出现一次)
|
|
|
|
|
|
|
|
|
|
**Step 2: 检查UI组件是否已添加**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
grep -E "查看导入失败记录|导入失败记录" ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue | wc -l
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: 输出应该大于等于2
|
|
|
|
|
|
|
|
|
|
**Step 3: 查看所有commit**
|
|
|
|
|
|
|
|
|
|
Run:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
```bash
|
|
|
|
|
git log --oneline --grep="purchase.*import\|导入" -10
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Expected: 显示本次实施的所有提交记录
|
|
|
|
|
|
|
|
|
|
**Step 4: 创建完成标记**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git tag -a "purchase-import-optimization" -m "采购交易导入功能优化完成
|
|
|
|
|
|
|
|
|
|
- 后台异步处理
|
|
|
|
|
- 通知提示
|
|
|
|
|
- 失败记录查看
|
|
|
|
|
- 状态持久化
|
|
|
|
|
|
|
|
|
|
实施日期: 2026-02-08"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Step 5: 最终提交**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git commit --allow-empty -m "feat: 采购交易导入功能优化完成 ✓
|
|
|
|
|
|
|
|
|
|
✅ 所有功能已实现
|
|
|
|
|
✅ 代码已提交
|
|
|
|
|
✅ 文档已更新
|
|
|
|
|
✅ 测试脚本已准备
|
|
|
|
|
|
|
|
|
|
实施计划: doc/plans/2026-02-08-purchase-transaction-import-implementation.md
|
|
|
|
|
设计文档: doc/plans/2026-02-08-purchase-transaction-import-design.md
|
|
|
|
|
变更日志: doc/plans/2026-02-08-purchase-transaction-import-changelog.md
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 附录
|
|
|
|
|
|
|
|
|
|
### A. 快速参考
|
|
|
|
|
|
|
|
|
|
**localStorage Key**: `purchase_transaction_import_last_task`
|
|
|
|
|
|
|
|
|
|
**API接口**:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- 导入: `POST /ccdi/purchaseTransaction/importData`
|
|
|
|
|
- 状态: `GET /ccdi/purchaseTransaction/importStatus/{taskId}`
|
|
|
|
|
- 失败记录: `GET /ccdi/purchaseTransaction/importFailures/{taskId}`
|
|
|
|
|
|
|
|
|
|
**轮询配置**:
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- 间隔: 2秒
|
|
|
|
|
- 超时: 150次(5分钟)
|
|
|
|
|
|
|
|
|
|
**状态保留**: 7天
|
|
|
|
|
|
|
|
|
|
### B. 故障排查
|
|
|
|
|
|
|
|
|
|
**问题**: 导入后没有显示通知
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- 检查: 浏览器控制台是否有错误
|
|
|
|
|
- 检查: `$notify`组件是否可用
|
|
|
|
|
- 检查: 响应数据是否包含taskId
|
|
|
|
|
|
|
|
|
|
**问题**: 无法查看失败记录
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- 检查: localStorage中是否有任务数据
|
|
|
|
|
- 检查: showFailureButton是否为true
|
|
|
|
|
- 检查: API返回的错误码
|
|
|
|
|
|
|
|
|
|
**问题**: 刷新页面后状态丢失
|
2026-03-03 16:14:16 +08:00
|
|
|
|
2026-02-08 13:44:13 +08:00
|
|
|
- 检查: localStorage是否被清除
|
|
|
|
|
- 检查: restoreImportState是否被调用
|
|
|
|
|
|
|
|
|
|
### C. 后续优化建议
|
|
|
|
|
|
|
|
|
|
1. 添加导入进度条显示
|
|
|
|
|
2. 支持取消正在进行的导入任务
|
|
|
|
|
3. 批量导入多个文件
|
|
|
|
|
4. 导入历史记录列表
|
|
|
|
|
5. 导入数据预览功能
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
**实施计划版本**: 1.0.0
|
|
|
|
|
**创建日期**: 2026-02-08
|
|
|
|
|
**预计工作量**: 2-3小时
|
|
|
|
|
**实际工作量**: __待填写__
|
|
|
|
|
**实施人员**: __待填写__
|