# 批量自动化 - 一键补差详细流程

## 📋 流程概览

**任务名称**: 一键补差 (dailyFix)  
**总步骤数**: 25个步骤（包含诊断）  
**子操作数**: 约70+个  
**预计执行时间**: 60-90秒/角色  
**统一超时**: 1000ms（1秒）  
**操作间隔**: 200ms（0.2秒）

---

## 🔍 完整执行流程

### ⚙️ 准备阶段

#### 步骤0：初始化任务状态
```javascript
dailyTaskStateStore.initTokenTaskState(tokenId)
```
- **说明**: 初始化本地任务跟踪状态
- **用途**: 记录哪些消耗资源的任务已完成，避免重复执行

#### 步骤0.1：获取执行前任务状态 🆕
```javascript
await client.sendWithPromise('role_getroleinfo', {}, 1000)
```
- **指令**: `role_getroleinfo`
- **参数**: `{}`
- **超时**: 1000ms
- **用途**: 获取当前角色的每日任务完成状态
- **输出**: 控制台显示 `📊 执行前任务状态: { "1": 0, "2": -1, ... }`
- **延迟**: 200ms

---

### 📝 第一阶段：基础日常任务（1-11）

#### 步骤1：分享游戏
```javascript
await client.sendWithPromise('system_mysharecallback', {
  isSkipShareCard: true,
  type: 2
}, 1000)
```
- **指令**: `system_mysharecallback`
- **参数**: `{ isSkipShareCard: true, type: 2 }`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **延迟**: 200ms
- **错误处理**: 失败不中断，继续执行

#### 步骤2：赠送好友金币
```javascript
await client.sendWithPromise('friend_batch', {}, 1000)
```
- **指令**: `friend_batch`
- **参数**: `{}`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **延迟**: 200ms

#### 步骤3：免费招募
```javascript
await client.sendWithPromise('hero_recruit', {
  recruitType: 3,
  recruitNumber: 1
}, 1000)
```
- **指令**: `hero_recruit`
- **参数**: `{ recruitType: 3, recruitNumber: 1 }`
  - `recruitType: 3` = 免费招募
  - `recruitNumber: 1` = 招募1次
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **延迟**: 200ms

#### 步骤4：付费招募 ⚠️
```javascript
await executeSubTask(tokenId, 'paid_recruit', '付费招募',
  async () => await client.sendWithPromise('hero_recruit', {
    recruitType: 1,
    recruitNumber: 1
  }, 1000),
  true // 消耗资源
)
```
- **指令**: `hero_recruit`
- **参数**: `{ recruitType: 1, recruitNumber: 1 }`
  - `recruitType: 1` = 付费招募
  - `recruitNumber: 1` = 招募1次
- **超时**: 1000ms
- **消耗资源**: ✅ 是（会被跟踪）
- **跳过逻辑**: 如果今天已完成，自动跳过
- **延迟**: 200ms（未跳过时）

#### 步骤5：免费点金（3次）⚠️
```javascript
// 循环3次
for (let i = 0; i < 3; i++) {
  await executeSubTask(tokenId, `buy_gold_${i+1}`, `免费点金 ${i+1}/3`,
    async () => await client.sendWithPromise('system_buygold', { buyNum: 1 }, 1000),
    true // 消耗资源
  )
}
```
- **指令**: `system_buygold` × 3
- **参数**: `{ buyNum: 1 }`
- **超时**: 1000ms
- **消耗资源**: ✅ 是（每次都会被跟踪）
- **跳过逻辑**: 每次独立判断，已完成的会跳过
- **子任务**:
  1. 免费点金 1/3 (`buy_gold_1`)
  2. 免费点金 2/3 (`buy_gold_2`)
  3. 免费点金 3/3 (`buy_gold_3`)
- **延迟**: 每次200ms（未跳过时）

#### 步骤6：开启木质宝箱×10 ⚠️
```javascript
await executeSubTask(tokenId, 'open_box', '开启木质宝箱×10',
  async () => await client.sendWithPromise('item_openbox', {
    itemId: 2001,
    number: 10
  }, 1000),
  true // 消耗资源
)
```
- **指令**: `item_openbox`
- **参数**: `{ itemId: 2001, number: 10 }`
  - `itemId: 2001` = 木质宝箱
  - `number: 10` = 开启10个
- **超时**: 1000ms
- **消耗资源**: ✅ 是
- **跳过逻辑**: 如果今天已完成，自动跳过
- **延迟**: 200ms（未跳过时）

#### 步骤7：福利签到
```javascript
await client.sendWithPromise('system_signinreward', {}, 1000)
```
- **指令**: `system_signinreward`
- **参数**: `{}`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **延迟**: 200ms

#### 步骤8：领取每日礼包
```javascript
await client.sendWithPromise('discount_claimreward', {}, 1000)
```
- **指令**: `discount_claimreward`
- **参数**: `{}`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **延迟**: 200ms

#### 步骤9：领取免费礼包
```javascript
await client.sendWithPromise('card_claimreward', {}, 1000)
```
- **指令**: `card_claimreward`
- **参数**: `{}`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **延迟**: 200ms

#### 步骤10：领取永久卡礼包
```javascript
await client.sendWithPromise('card_claimreward', { cardId: 4003 }, 1000)
```
- **指令**: `card_claimreward`
- **参数**: `{ cardId: 4003 }`
  - `cardId: 4003` = 永久卡
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **延迟**: 200ms

#### 步骤11：领取邮件奖励
```javascript
await client.sendWithPromise('mail_claimallattachment', { category: 0 }, 1000)
```
- **指令**: `mail_claimallattachment`
- **参数**: `{ category: 0 }`
  - `category: 0` = 所有类别
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **延迟**: 200ms

---

### 🎣 第二阶段：免费活动（12-14）

#### 步骤12：免费钓鱼（3次）⚠️
```javascript
// 循环3次
for (let i = 0; i < 3; i++) {
  await executeSubTask(tokenId, `fish_${i+1}`, `免费钓鱼 ${i+1}/3`,
    async () => await client.sendWithPromise('artifact_lottery', {
      lotteryNumber: 1,
      newFree: true,
      type: 1
    }, 1000),
    true // 消耗资源
  )
}
```
- **指令**: `artifact_lottery` × 3
- **参数**: `{ lotteryNumber: 1, newFree: true, type: 1 }`
  - `lotteryNumber: 1` = 钓鱼1次
  - `newFree: true` = 使用免费次数
  - `type: 1` = 普通钓鱼
- **超时**: 1000ms
- **消耗资源**: ✅ 是（每次都会被跟踪）
- **跳过逻辑**: 每次独立判断
- **子任务**:
  1. 免费钓鱼 1/3 (`fish_1`)
  2. 免费钓鱼 2/3 (`fish_2`)
  3. 免费钓鱼 3/3 (`fish_3`)
- **延迟**: 每次200ms（未跳过时）

#### 步骤13：灯神免费扫荡（4个国家）
```javascript
// 循环4个国家
const kingdoms = ['魏国', '蜀国', '吴国', '群雄']
for (let gid = 1; gid <= 4; gid++) {
  await client.sendWithPromise('genie_sweep', { genieId: gid }, 1000)
}
```
- **指令**: `genie_sweep` × 4
- **参数**: `{ genieId: 1/2/3/4 }`
  - `genieId: 1` = 魏国
  - `genieId: 2` = 蜀国
  - `genieId: 3` = 吴国
  - `genieId: 4` = 群雄
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **子任务**:
  1. 魏国灯神免费扫荡
  2. 蜀国灯神免费扫荡
  3. 吴国灯神免费扫荡
  4. 群雄灯神免费扫荡
- **延迟**: 每次200ms

#### 步骤14：领取免费扫荡卷（3次）
```javascript
// 循环3次
for (let i = 0; i < 3; i++) {
  await client.sendWithPromise('genie_buysweep', {}, 1000)
}
```
- **指令**: `genie_buysweep` × 3
- **参数**: `{}`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **子任务**:
  1. 领取免费扫荡卷 1/3
  2. 领取免费扫荡卷 2/3
  3. 领取免费扫荡卷 3/3
- **延迟**: 每次200ms

---

### 🛒 第三阶段：购买和战斗（15-18）

#### 步骤15：黑市一键采购 ⚠️
```javascript
await executeSubTask(tokenId, 'black_market', '黑市一键采购',
  async () => await client.sendWithPromise('store_purchase', { goodsId: 1 }, 1000),
  true // 消耗资源
)
```
- **指令**: `store_purchase`
- **参数**: `{ goodsId: 1 }`
  - `goodsId: 1` = 第一个商品（通常是黑市刷新的商品）
- **超时**: 1000ms
- **消耗资源**: ✅ 是
- **跳过逻辑**: 如果今天已完成，自动跳过
- **延迟**: 200ms（未跳过时）

#### 步骤16：竞技场战斗（3次，用阵容1）⚠️
```javascript
// 1. 切换到阵容1
await switchToFormation(client, 1)

// 2. 开始竞技场
await client.sendWithPromise('arena_startarea', {}, 1000)

// 3. 进行3场战斗
for (let i = 1; i <= 3; i++) {
  await executeSubTask(tokenId, `arena_${i}`, `竞技场战斗 ${i}/3`,
    async () => {
      // 获取目标
      const targets = await client.sendWithPromise('arena_getareatarget', {
        refresh: false
      }, 1000)
      
      const targetId = targets?.roleList?.[0]?.roleId
      if (!targetId) throw new Error('未找到目标')
      
      // 开始战斗
      await client.sendWithPromise('fight_startareaarena', { targetId }, 1000)
      
      return { targetId }
    },
    true // 消耗资源
  )
}
```
- **前置操作**: 切换到阵容1
- **指令序列**:
  1. `role_setformation` (切换阵容)
  2. `arena_startarea` (开始竞技场)
  3. `arena_getareatarget` × 3 (获取目标)
  4. `fight_startareaarena` × 3 (开始战斗)
- **超时**: 每个操作1000ms
- **消耗资源**: ✅ 是（每场战斗独立跟踪）
- **跳过逻辑**: 每场战斗独立判断
- **子任务**:
  1. 竞技场战斗 1/3 (`arena_1`)
  2. 竞技场战斗 2/3 (`arena_2`)
  3. 竞技场战斗 3/3 (`arena_3`)
- **延迟**: 每次200ms（未跳过时）

#### 步骤17：军团BOSS（用阵容1）
```javascript
// 1. 切换到阵容1
await switchToFormation(client, 1)

// 2. 打军团BOSS
await client.sendWithPromise('fight_startlegionboss', {}, 1000)
```
- **前置操作**: 切换到阵容1
- **指令**: `fight_startlegionboss`
- **参数**: `{}`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **延迟**: 200ms

#### 步骤18：每日BOSS/咸王考验（3次，用阵容1）
```javascript
// 1. 切换到阵容1
await switchToFormation(client, 1)

// 2. 获取今日BOSS ID
const todayBossId = getTodayBossId() // 根据星期几确定BOSS ID

// 3. 进行3场战斗
for (let i = 1; i <= 3; i++) {
  await client.sendWithPromise('fight_startboss', { bossId: todayBossId }, 1000)
}
```
- **前置操作**: 切换到阵容1，获取今日BOSS ID
- **指令**: `fight_startboss` × 3
- **参数**: `{ bossId: todayBossId }`
  - `todayBossId` 根据星期几自动计算
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **子任务**:
  1. 每日BOSS 1/3
  2. 每日BOSS 2/3
  3. 每日BOSS 3/3
- **延迟**: 每次200ms

---

### 🤖 第四阶段：盐罐机器人（19）

#### 步骤19：重启盐罐机器人服务

##### 步骤19.1：停止盐罐机器人
```javascript
await client.sendWithPromise('bottlehelper_stop', { bottleType: -1 }, 1000)
```
- **指令**: `bottlehelper_stop`
- **参数**: `{ bottleType: -1 }`
  - `bottleType: -1` = 全部类型
- **超时**: 1000ms
- **错误处理**: 如果机器人未启动，跳过此步骤（不影响后续流程）
- **延迟**: 500ms

##### 步骤19.2：启动盐罐机器人
```javascript
await client.sendWithPromise('bottlehelper_start', { bottleType: -1 }, 1000)
```
- **指令**: `bottlehelper_start`
- **参数**: `{ bottleType: -1 }`
  - `bottleType: -1` = 全部类型
- **超时**: 1000ms
- **延迟**: 500ms

##### 步骤19.3：领取盐罐奖励
```javascript
await client.sendWithPromise('bottlehelper_claim', {}, 1000)
```
- **指令**: `bottlehelper_claim`
- **参数**: `{}`
- **超时**: 1000ms
- **延迟**: 200ms

---

### 🎁 第五阶段：领取奖励（20-22）

#### 步骤20：领取任务奖励（1-10）

##### 重要：等待服务器状态更新
```javascript
console.log('⏳ 等待服务器更新任务状态（1秒）...')
await new Promise(resolve => setTimeout(resolve, 1000))
```
- **延迟**: 1000ms
- **原因**: 
  - 完成任务和领取奖励是两个独立操作
  - 服务器需要时间同步任务完成状态
  - 如果不等待，可能出现"任务已完成但领取失败"
  - 第二次运行才能成功

##### 领取任务奖励1-10
```javascript
// 循环10次
for (let taskId = 1; taskId <= 10; taskId++) {
  await client.sendWithPromise('task_claimdailypoint', { taskId }, 1000)
}
```
- **指令**: `task_claimdailypoint` × 10
- **参数**: `{ taskId: 1~10 }`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **子任务**:
  1. 领取任务奖励1
  2. 领取任务奖励2
  3. 领取任务奖励3
  4. 领取任务奖励4
  5. 领取任务奖励5
  6. 领取任务奖励6
  7. 领取任务奖励7
  8. 领取任务奖励8
  9. 领取任务奖励9
  10. 领取任务奖励10
- **延迟**: 每次200ms

#### 步骤21：领取日常任务奖励
```javascript
await client.sendWithPromise('task_claimdailyreward', {}, 1000)
```
- **指令**: `task_claimdailyreward`
- **参数**: `{}`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **说明**: 领取每日任务的总积分奖励
- **延迟**: 200ms

#### 步骤22：领取周常任务奖励
```javascript
await client.sendWithPromise('task_claimweekreward', {}, 1000)
```
- **指令**: `task_claimweekreward`
- **参数**: `{}`
- **超时**: 1000ms
- **消耗资源**: ❌ 否
- **说明**: 领取周常任务的总积分奖励
- **延迟**: 200ms

---

### 📊 诊断阶段 🆕

#### 步骤23：获取执行后任务状态
```javascript
await client.sendWithPromise('role_getroleinfo', {}, 1000)
```
- **指令**: `role_getroleinfo`
- **参数**: `{}`
- **超时**: 1000ms
- **用途**: 获取执行后的每日任务完成状态
- **输出**: 控制台显示 `📊 执行后任务状态: { "1": -1, "2": -1, ... }`

#### 步骤24：对比任务状态变化
```javascript
// 对比执行前后的状态
for (const taskId of allTaskIds) {
  const before = beforeTaskStatus[taskId] || 0
  const after = afterTaskStatus[taskId] || 0
  const changed = before !== after
  
  if (changed) {
    console.log(`任务${taskId}: ${before} → ${after} ✅`)
  } else {
    console.log(`任务${taskId}: ${after} (无变化)`)
  }
}
```
- **输出**: 控制台显示任务状态对比分析
- **包含信息**:
  - 哪些任务从"未完成"变为"已完成"
  - 哪些任务执行前后都是"未完成"（问题任务）
  - 统计信息：已完成数/总任务数，本次改变数

#### 步骤25：生成统计报告
```javascript
const completedCount = Object.values(afterTaskStatus).filter(v => v === -1).length
const totalCount = Object.keys(afterTaskStatus).length
const changedCount = taskStatusComparison.filter(t => t.changed).length

console.log(`📊 统计: 已完成 ${completedCount}/${totalCount}，本次改变 ${changedCount} 个任务`)
```
- **输出**: 最终统计信息
- **返回**: 将诊断结果添加到返回数据中

---

## 📊 统计信息

### 执行时间分析

| 阶段 | 操作数 | 预计时间 |
|-----|-------|---------|
| 准备阶段 | 2 | 2秒 |
| 基础日常 (1-11) | 11 | 14秒 |
| 免费活动 (12-14) | 10 | 13秒 |
| 购买战斗 (15-18) | 13 | 17秒 |
| 盐罐机器人 (19) | 3 | 2.2秒 |
| 领取奖励 (20-22) | 12 | 14.4秒 |
| 诊断阶段 (23-25) | 2 | 2秒 |
| **总计** | **53** | **64.6秒** |

**实际时间**: 60-90秒（考虑网络延迟和服务器响应时间）

### 资源消耗任务

共有 **12个** 会消耗资源的任务，执行前会检查是否已完成：

| 序号 | 任务名称 | 任务ID | 可跳过 |
|-----|---------|--------|-------|
| 1 | 付费招募 | `paid_recruit` | ✅ |
| 2 | 免费点金 1/3 | `buy_gold_1` | ✅ |
| 3 | 免费点金 2/3 | `buy_gold_2` | ✅ |
| 4 | 免费点金 3/3 | `buy_gold_3` | ✅ |
| 5 | 开启木质宝箱×10 | `open_box` | ✅ |
| 6 | 免费钓鱼 1/3 | `fish_1` | ✅ |
| 7 | 免费钓鱼 2/3 | `fish_2` | ✅ |
| 8 | 免费钓鱼 3/3 | `fish_3` | ✅ |
| 9 | 黑市一键采购 | `black_market` | ✅ |
| 10 | 竞技场战斗 1/3 | `arena_1` | ✅ |
| 11 | 竞技场战斗 2/3 | `arena_2` | ✅ |
| 12 | 竞技场战斗 3/3 | `arena_3` | ✅ |

**跳过机制**：
- 如果某个任务今天已完成，会自动跳过
- 控制台显示：`⏭️ 跳过已完成的任务: XXX`
- 避免重复消耗资源

---

## ⚙️ 辅助函数

### switchToFormation(client, formationId)
```javascript
async function switchToFormation(client, formationId) {
  await client.sendWithPromise('role_setformation', {
    formationId: formationId
  }, 1000)
}
```
- **用途**: 切换阵容
- **参数**: `formationId` (1-10)
- **超时**: 1000ms
- **使用场景**: 竞技场战斗、军团BOSS、每日BOSS前

### getTodayBossId()
```javascript
function getTodayBossId() {
  const dayOfWeek = new Date().getDay() // 0-6 (周日-周六)
  const bossIds = [7, 1, 2, 3, 4, 5, 6] // BOSS ID映射
  return bossIds[dayOfWeek]
}
```
- **用途**: 根据星期几获取今日BOSS ID
- **返回**: BOSS ID (1-7)
- **映射关系**:
  - 周日 → BOSS 7
  - 周一 → BOSS 1
  - 周二 → BOSS 2
  - 周三 → BOSS 3
  - 周四 → BOSS 4
  - 周五 → BOSS 5
  - 周六 → BOSS 6

### executeSubTask(tokenId, taskId, taskName, executor, consumesResources)
```javascript
async function executeSubTask(tokenId, taskId, taskName, executor, consumesResources) {
  // 1. 检查是否已完成（如果消耗资源）
  if (consumesResources && dailyTaskStateStore.isTaskCompleted(tokenId, taskId)) {
    console.log(`⏭️ 跳过已完成的任务: ${taskName}`)
    return { task: taskName, taskId, skipped: true, success: true, message: '已完成，跳过执行' }
  }
  
  // 2. 执行任务
  try {
    const result = await executor()
    dailyTaskStateStore.markTaskCompleted(tokenId, taskId, true, null)
    console.log(`✅ ${taskName} - 成功`)
    return { task: taskName, taskId, success: true, data: result, skipped: false }
  } catch (error) {
    dailyTaskStateStore.markTaskFailed(tokenId, taskId, error.message)
    console.log(`❌ ${taskName} - 失败: ${error.message}`)
    return { task: taskName, taskId, success: false, error: error.message, skipped: false }
  }
}
```
- **用途**: 执行单个子任务，支持跳过已完成的资源消耗任务
- **参数**:
  - `tokenId`: Token ID
  - `taskId`: 任务ID（用于跟踪）
  - `taskName`: 任务名称
  - `executor`: 执行函数
  - `consumesResources`: 是否消耗资源
- **返回**: 任务执行结果对象

---

## 🎯 流程特点

### 1. 智能跳过机制
- ✅ 自动跳过已完成的资源消耗任务
- ✅ 避免重复浪费金币、宝箱等资源
- ✅ 可以多次运行一键补差，只会执行未完成的任务

### 2. 错误容错机制
- ✅ 单个任务失败不会中断整体流程
- ✅ 所有错误都会被记录
- ✅ 继续执行后续任务

### 3. 状态同步延迟
- ✅ 在领取任务奖励前等待1秒
- ✅ 确保服务器状态已同步
- ✅ 提高任务奖励领取成功率

### 4. 任务状态诊断 🆕
- ✅ 执行前获取任务状态
- ✅ 执行后获取任务状态
- ✅ 自动对比分析
- ✅ 显示哪些任务未完成
- ✅ 帮助定位问题

### 5. 统一超时设置
- ✅ 所有操作统一1000ms超时
- ✅ 简化配置，易于维护
- ✅ 平衡速度和稳定性

---

## 📝 控制台输出示例

### 正常执行流程
```
🔍 正在获取执行前的任务完成状态...
📊 执行前任务状态: {
  "1": 0,
  "2": -1,
  "3": 0,
  "4": -1,
  ...
}

📋 一键补差包含以下子任务：
1. 分享游戏
2. 赠送好友金币
...
总计：22大类，约70+个子操作
超时时间：统一1000ms
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✅ 分享游戏 - 成功
✅ 赠送好友金币 - 成功
✅ 免费招募 - 成功
⏭️ 跳过已完成的任务: 付费招募
✅ 免费点金 1/3 - 成功
⏭️ 跳过已完成的任务: 免费点金 2/3
⏭️ 跳过已完成的任务: 免费点金 3/3
...
⏳ 等待服务器更新任务状态（1秒）...
✅ 领取任务奖励1 - 成功
✅ 领取任务奖励2 - 成功
...

🔍 正在获取执行后的任务完成状态...
📊 执行后任务状态: {
  "1": -1,
  "2": -1,
  ...
}

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 每日任务完成状态对比分析
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
任务1: 未完成 → 已完成 ✅ 已完成
任务2: 已完成 (无变化) ✅ 已完成
任务3: 未完成 → 已完成 ✅ 已完成
...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 统计: 已完成 10/10，本次改变 8 个任务
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

### 出现错误时
```
✅ 分享游戏 - 成功
❌ 赠送好友金币 - 失败: 好友列表为空
✅ 免费招募 - 成功
...（继续执行后续任务）
```

---

## 🔧 代码位置

**文件**: `src/stores/batchTaskStore.js`  
**函数**: `executeTask`  
**分支**: `case 'dailyFix'`  
**行数**: 约424-881行

---

## 📚 相关文档

- **一键补差完整子任务清单.md** - 任务列表概览
- **功能更新-任务状态诊断.md** - 诊断功能详解
- **游戏内每日任务ID对应表.md** - 任务ID对应关系
- **问题修复-任务奖励领取失败.md** - 1秒延迟的原因
- **功能更新-任务状态跟踪.md** - 资源跳过机制

---

**文档创建日期**: 2025-10-07  
**版本**: v3.3.0  
**状态**: ✅ 最新


