# 问题修复 - 批量任务统计计数错误 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修复 - **优先级**: 最高(影响核心统计逻辑) - **影响范围**: 所有批量任务执行