Files
xyzw_web_helper/MD说明文件夹/问题修复-批量任务统计计数错误v3.6.1.md
2025-10-17 20:56:50 +08:00

311 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 问题修复 - 批量任务统计计数错误 v3.6.1
## 📌 修复时间
2025-10-07
## 🐛 问题描述
### 现象
在批量自动化任务执行过程中,出现**严重的统计错误**
#### 统计数据异常
- **总计**: 318个token
- **成功**: 132个
- **失败**: 0个 ❌(明显错误)
- **跳过**: 0个
- **遗失**: 186个token未被统计
#### 显示矛盾
大量token卡片出现自相矛盾的显示
- ❌ 状态标签:**"已完成"**(绿色)
- ❌ 显示文字:**"失败名"**(红色)
- **矛盾**失败的token被错误标记为"已完成"
### 用户反馈
1. > "明明有存在失败的没有进行wss链接的token卡片但是总计却没有显示失败的"
2. > "有大量失败的token卡片显示已完成可能这是导致失败统计错误的关键" ✅(关键发现)
## 🔍 问题分析
### 核心问题(主要)⚠️
#### 问题1: 子任务失败被忽略
`executeTokenTasks` 函数第327-413行存在严重逻辑错误
```javascript:src/stores/batchTaskStore.js {360-382} 原代码
} catch (error) {
console.error(` ❌ 任务失败: ${taskName}`, error.message)
// 保存错误信息
taskProgress.value[tokenId].result[taskName] = {
success: false,
error: error.message
}
// ❌ 问题:只记录错误,没有统计失败数量
// 继续执行下一个任务(单个任务失败不影响整体)
}
// ❌ 核心问题:无论上面有多少任务失败,都标记为完成
updateTaskProgress(tokenId, {
status: 'completed', // ❌ 错误!
progress: 100,
currentTask: null,
endTime: Date.now()
})
executionStats.value.success++ // ❌ 错误!计入成功
console.log(`✅ Token完成: ${token.name}`)
```
**问题本质**
- for循环中的catch块捕获了子任务错误
- 但只是记录错误,继续执行下一个任务
- **循环结束后,无论有多少任务失败,都标记为"completed"并计入成功**
- 这导致所有token都显示"已完成",即使所有子任务都失败了
### 次要问题
#### 问题2: Promise异常处理不完整
在 `executeBatchWithConcurrency` 函数中外层catch块未更新失败计数已在上次提交修复
## ✅ 解决方案
### 修复1: 智能状态判断(核心修复)
添加失败计数和智能状态判断逻辑:
```javascript:src/stores/batchTaskStore.js {327-413} 修复后
// 依次执行任务
let taskFailedCount = 0 // 🆕 记录失败的任务数量
for (let i = 0; i < tasks.length; i++) {
// ... 任务执行代码 ...
try {
const result = await executeTask(tokenId, taskName)
// ... 成功处理 ...
} catch (error) {
console.error(` ❌ 任务失败: ${taskName}`, error.message)
taskProgress.value[tokenId].result[taskName] = {
success: false,
error: error.message
}
taskFailedCount++ // 🆕 增加失败计数
}
}
// 🆕 根据任务执行情况决定最终状态
const hasAnyTaskFailed = taskFailedCount > 0
const allTasksFailed = taskFailedCount === tasks.length
if (allTasksFailed) {
// 所有任务都失败 - 标记为失败
updateTaskProgress(tokenId, {
status: 'failed',
progress: 100,
currentTask: null,
error: `所有任务执行失败 (${taskFailedCount}/${tasks.length})`,
endTime: Date.now()
})
executionStats.value.failed++
console.log(`❌ Token失败: ${token.name} (所有任务都失败)`)
} else if (hasAnyTaskFailed) {
// 部分任务失败 - 标记为部分完成(视为完成但记录错误)
updateTaskProgress(tokenId, {
status: 'completed',
progress: 100,
currentTask: null,
error: `部分任务失败 (${taskFailedCount}/${tasks.length})`,
endTime: Date.now()
})
executionStats.value.success++
console.log(`⚠️ Token部分完成: ${token.name} (${taskFailedCount}个任务失败)`)
} else {
// 所有任务成功 - 标记为完成
updateTaskProgress(tokenId, {
status: 'completed',
progress: 100,
currentTask: null,
endTime: Date.now()
})
executionStats.value.success++
console.log(`✅ Token完成: ${token.name}`)
}
```
### 修复逻辑
#### 三种状态判断
1. **所有任务失败** (`taskFailedCount === tasks.length`)
- 标记为 `'failed'`
- 计入失败统计
- 记录详细错误信息
2. **部分任务失败** (`taskFailedCount > 0`)
- 标记为 `'completed'`(视为部分完成)
- 计入成功统计(因为至少完成了部分任务)
- 在error字段记录失败信息便于查看
3. **所有任务成功** (`taskFailedCount === 0`)
- 标记为 `'completed'`
- 计入成功统计
#### 设计考量
- **为什么部分失败算成功?**
- 一键补差有40+个子任务
- 如果1个任务失败就算整体失败会导致成功率过低
- 部分完成仍有价值(大部分奖励已领取)
- 通过error字段可查看具体失败了哪些任务
- **如何区分部分失败和全部成功?**
- 查看token卡片的error信息
- 部分失败会显示:`部分任务失败 (3/43)`
- 全部成功不会有error信息
### 修复2: Promise异常处理补充
在外层catch中添加状态检查避免重复计数
```javascript:src/stores/batchTaskStore.js {257-279}
.catch(error => {
console.error(`❌ Token ${tokenId} 执行失败:`, error)
// 🆕 确保失败计数被正确更新
const tokenProgress = taskProgress.value[tokenId]
if (!tokenProgress || tokenProgress.status === 'pending' || tokenProgress.status === 'executing') {
// 只有当状态还未最终确定时才更新(避免重复计数)
updateTaskProgress(tokenId, {
status: 'failed',
error: error.message,
endTime: Date.now()
})
executionStats.value.failed++
}
// 清理执行队列
const index = executing.indexOf(promise)
if (index > -1) {
executing.splice(index, 1)
}
executingTokens.value.delete(tokenId)
})
```
## 📊 修复效果对比
### 修复前(错误)
```
总计: 318
成功: 132 ← 包含了大量实际失败的token
失败: 0 ← 错误!所有失败都被误判为成功
跳过: 0
合计: 132 ← 遗失了186个token
Token显示矛盾
- 状态:已完成(绿色)❌
- 文字:失败名(红色)❌
```
### 修复后(正确)
```
总计: 318
成功: X ← 只包含真正成功或部分完成的token
失败: Y ← 正确统计所有任务都失败的token
跳过: 0
合计: 318 ← 完整统计
Token显示一致
- 所有任务失败:状态=失败(红色),文字=失败名(红色)✅
- 部分任务失败:状态=已完成绿色error=部分任务失败 (X/43)
- 所有任务成功:状态=已完成(绿色),无错误信息
```
## 🔧 涉及文件
- `src/stores/batchTaskStore.js`
- 第327-413行`executeTokenTasks` 函数(核心修复)
- 第257-279行Promise异常处理补充修复
## 📝 测试建议
### 测试场景1: 所有任务失败
1. 断开网络或使用无效token
2. 执行批量任务
3. 验证:
- ✅ token状态标记为"失败"
- ✅ 失败计数正确增加
- ✅ error显示`所有任务执行失败 (6/6)`
### 测试场景2: 部分任务失败
1. 使用正常token但模拟部分子任务失败
2. 验证:
- ✅ token状态标记为"已完成"
- ✅ 成功计数增加
- ✅ error显示`部分任务失败 (2/6)`
### 测试场景3: 所有任务成功
1. 使用正常token和网络
2. 验证:
- ✅ token状态标记为"已完成"
- ✅ 成功计数增加
- ✅ error为空
### 测试场景4: 高并发混合场景
1. 并发100个token成功、部分失败、全部失败混合
2. 验证:
- ✅ `成功 + 失败 + 跳过 = 总计`
- ✅ 不存在"遗失"的统计
- ✅ 每个token状态与实际情况一致
## 🎯 预期结果
### 统计准确性
- ✅ 所有token都被正确统计
- ✅ `成功 + 失败 + 跳过 = 总计`
- ✅ 失败计数准确反映"所有任务都失败"的token数量
- ✅ 成功计数包含"全部成功"和"部分成功"的token
### 显示一致性
- ✅ token状态与实际执行结果一致
- ✅ 不再出现"已完成"但显示"失败名"的矛盾
- ✅ 部分失败的token通过error字段明确标识
### 用户体验
- ✅ 清晰了解哪些token完全失败
- ✅ 可通过error信息查看部分失败详情
- ✅ 统计数据可信,便于决策
## 📌 注意事项
### 1. 部分失败的处理策略
- 部分失败计入"成功"是合理的设计
- 一键补差有40+个子任务,允许部分容错
- 用户可通过详情查看具体失败的子任务
### 2. 避免重复计数
- 通过 `taskFailedCount` 精确统计失败数量
- 外层catch通过状态检查避免重复更新
- 确保每个token只被计入一次
### 3. 错误信息保留
- 所有失败都会记录详细错误信息
- 部分失败会注明失败比例
- 便于后续排查和优化
## 🔗 相关文档
- [批量自动化-一键补差详细流程.md](./批量自动化-一键补差详细流程.md)
- [高并发WebSocket连接优化方案.md](./高并发WebSocket连接优化方案.md)
- [更新日志-高并发连接优化v3.3.2.md](./更新日志-高并发连接优化v3.3.2.md)
## 📅 版本信息
- **版本号**: v3.6.1
- **修复日期**: 2025-10-07
- **问题类型**: 严重Bug修复
- **优先级**: 最高(影响核心统计逻辑)
- **影响范围**: 所有批量任务执行