10 KiB
10 KiB
功能优化 - 同步服务器发车次数 (v3.10.0)
📋 优化背景
v3.9.9 测试发现的问题
在v3.9.9测试中,发现了客户端和服务器端发车次数不一致的问题:
| 位置 | 今日发车次数 | 是否达到上限 |
|---|---|---|
| 客户端(localStorage) | 0/4 | 否 |
| 服务器端 | ?/4 | 是(错误码12000050) |
问题原因:
- 客户端使用
localStorage存储发车次数 - 用户可能清除缓存或在不同设备登录
- 服务器端的发车次数是权威数据源
- 导致客户端和服务器端数据不一致
💡 v3.10.0 解决方案
核心思路
服务器端数据为准,客户端实时同步:
- 每次查询车辆时,获取服务器端的
sendCount - 与客户端
localStorage中的值比较 - 如果不一致,以服务器端为准,更新本地存储
- 在发送前再次确认,避免不必要的发送尝试
优化点
1. 查询车辆时同步发车次数
位置: 初次查询车辆后
代码:
// 获取服务器端的发车次数并同步到本地
const serverSendCount = queryResponse.roleCar?.sendCount || 0
const dailySendKey = getTodayKey(tokenId)
let dailySendCount = parseInt(localStorage.getItem(dailySendKey) || '0')
// 以服务器端的值为准(服务器端更权威)
if (serverSendCount !== dailySendCount) {
console.log(`🔄 [${tokenId}] 同步服务器发车次数: 客户端${dailySendCount} → 服务器${serverSendCount}`)
localStorage.setItem(dailySendKey, serverSendCount.toString())
dailySendCount = serverSendCount
}
console.log(`✅ [${tokenId}] 查询到 ${carIds.length} 辆车(今日已发车: ${dailySendCount}/4)`)
效果:
- ✅ 立即发现并修正客户端和服务器端的差异
- ✅ 提前告知用户真实的发车次数
- ✅ 避免后续不必要的操作
2. 刷新车辆后再次同步
位置: 批量刷新车辆并重新查询后
代码:
// 重新查询车辆状态
const reQueryResponse = await tokenStore.sendMessageAsync(tokenId, 'car_getrolecar', {}, 20000)
if (reQueryResponse?.roleCar?.carDataMap) {
Object.assign(carDataMap, reQueryResponse.roleCar.carDataMap)
}
// 同步服务器端的发车次数
if (reQueryResponse?.roleCar?.sendCount !== undefined) {
const newServerSendCount = reQueryResponse.roleCar.sendCount
if (newServerSendCount !== dailySendCount) {
console.log(`🔄 [${tokenId}] 刷新后同步发车次数: ${dailySendCount} → ${newServerSendCount}`)
localStorage.setItem(dailySendKey, newServerSendCount.toString())
dailySendCount = newServerSendCount
}
}
效果:
- ✅ 确保刷新操作后数据依然同步
- ✅ 检测是否有其他设备/页面发车
3. 发送前最后一次确认
位置: 等待3秒状态同步后,发送车辆前
代码:
// 重新查询车辆状态
console.log(`🔍 [${tokenId}] 重新查询车辆状态...`)
const finalQueryResponse = await tokenStore.sendMessageAsync(tokenId, 'car_getrolecar', {}, 20000)
if (finalQueryResponse?.roleCar?.carDataMap) {
Object.assign(carDataMap, finalQueryResponse.roleCar.carDataMap)
}
// 同步服务器端的发车次数(发送前最后一次确认)
if (finalQueryResponse?.roleCar?.sendCount !== undefined) {
const latestServerSendCount = finalQueryResponse.roleCar.sendCount
if (latestServerSendCount !== dailySendCount) {
console.log(`🔄 [${tokenId}] 发送前同步发车次数: ${dailySendCount} → ${latestServerSendCount}`)
localStorage.setItem(dailySendKey, latestServerSendCount.toString())
dailySendCount = latestServerSendCount
}
}
// 最后检查发车次数限制
const currentRemainingSendCount = 4 - dailySendCount
if (currentRemainingSendCount <= 0) {
console.warn(`⚠️ [${tokenId}] 发送前检查: 今日发车次数已达上限(${dailySendCount}/4),跳过发送`)
sendCarResults.push({
task: '批量发送',
success: true,
message: `今日发车次数已达上限(${dailySendCount}/4),跳过发送`
})
return {
task: '发车',
taskId: 'send_car',
success: true,
data: sendCarResults,
message: `今日发车次数已达上限(${dailySendCount}/4)`
}
}
效果:
- ✅ 发送前最后一次检查,避免浪费发送请求
- ✅ 如果已达上限,提前退出并告知用户
- ✅ 使用最新的发车次数计算剩余额度
4. 增强错误处理
位置: 发送车辆失败时
代码:
catch (error) {
const errorMsg = error.message || String(error)
// 区分不同的错误类型
if (errorMsg.includes('12000050')) {
console.log(`⚠️ [${tokenId}] 车辆 ${carId} 发送失败: 今日发车次数已达上限(服务器端限制)`)
} else if (errorMsg.includes('200020')) {
console.log(`⚠️ [${tokenId}] 车辆 ${carId} 发送失败: 处于冷却期或状态未同步`)
} else {
console.log(`❌ [${tokenId}] 发送车辆失败: ${carId} - ${errorMsg}`)
}
}
效果:
- ✅ 清晰区分不同类型的失败原因
- ✅ 用户能快速理解问题所在
- ✅ 避免误认为是bug
📊 优化效果对比
修改前(v3.9.9及之前)
📊 [token_xxx] 今日已发车次数: 0/4 ← 客户端数据(可能不准确)
🚀 [token_xxx] 待发车: 4辆,剩余额度: 4个,将发送: 4辆
❌ [token_xxx] 发送车辆失败: xxx - 服务器错误: 12000050 - 未知错误
❌ [token_xxx] 发送车辆失败: xxx - 服务器错误: 12000050 - 未知错误
❌ [token_xxx] 发送车辆失败: xxx - 服务器错误: 12000050 - 未知错误
❌ [token_xxx] 发送车辆失败: xxx - 服务器错误: 12000050 - 未知错误
🚀 [token_xxx] 发送完成:成功0次,跳过0次
问题:
- ❌ 客户端显示 0/4,但服务器认为已达上限
- ❌ 尝试发送4辆车,全部失败
- ❌ 错误信息不明确("未知错误")
- ❌ 浪费了4次发送请求
修改后(v3.10.0)
场景1:服务器端已达上限
✅ [token_xxx] 查询到 4 辆车(今日已发车: 0/4)
🔄 [token_xxx] 同步服务器发车次数: 客户端0 → 服务器4 ← 立即发现差异
✅ [token_xxx] 查询到 4 辆车(今日已发车: 4/4) ← 更新显示
📊 [token_xxx] 检查每日发车次数限制: 4/4
⚠️ [token_xxx] 今日发车次数已达上限: 4/4 ← 提前检测
🚀 [token_xxx] 开始批量发送...
⏳ [token_xxx] 等待服务器状态同步(3秒)...
🔍 [token_xxx] 重新查询车辆状态...
⚠️ [token_xxx] 发送前检查: 今日发车次数已达上限(4/4),跳过发送 ← 提前退出
效果:
- ✅ 立即发现并修正数据差异
- ✅ 提前检测到已达上限
- ✅ 避免了4次无效的发送请求
- ✅ 清晰告知用户原因
场景2:服务器端还有额度
✅ [token_xxx] 查询到 4 辆车(今日已发车: 0/4)
🔄 [token_xxx] 同步服务器发车次数: 客户端0 → 服务器2 ← 同步差异
✅ [token_xxx] 查询到 4 辆车(今日已发车: 2/4) ← 更新显示
📊 [token_xxx] 检查每日发车次数限制: 2/4
🚀 [token_xxx] 开始批量发送...
⏳ [token_xxx] 等待服务器状态同步(3秒)...
🔍 [token_xxx] 重新查询车辆状态...
🚀 [token_xxx] 待发车: 4辆,剩余额度: 2个,将发送: 2辆 ← 正确计算
✅ [token_xxx] 发送车辆成功: xxx
✅ [token_xxx] 发送车辆成功: xxx
🚀 [token_xxx] 发送完成:成功2次,跳过0次,今日4/4 ← 完美!
效果:
- ✅ 同步真实的发车次数
- ✅ 正确计算剩余额度
- ✅ 成功发送2辆车(不多不少)
- ✅ 最终达到每日上限 4/4
🎯 关键改进点总结
| 优化点 | 修改前 | 修改后 |
|---|---|---|
| 数据来源 | 只使用客户端 localStorage | 以服务器端为准,实时同步 |
| 同步时机 | 只在发送成功后更新 | 查询、刷新、发送前都同步 |
| 错误处理 | 通用错误信息 | 区分 12000050、200020 等错误码 |
| 提前检测 | 无 | 发送前检测并提前退出 |
| 用户体验 | 尝试发送才知道失败 | 提前告知,避免无效请求 |
| 日志清晰度 | 显示客户端数据(可能不准) | 显示真实数据并标注同步 |
📝 测试建议
测试场景1:客户端数据过期
- 在游戏功能页面手动发车2辆
- 清除浏览器 localStorage
- 在批量自动化中发车
- 预期:自动同步服务器端的2次记录,只发送剩余2辆
测试场景2:服务器端已达上限
- 确保服务器端已有4次发车记录
- 在批量自动化中尝试发车
- 预期:
- 查询时立即发现并同步(0→4)
- 提前检测到已达上限
- 跳过发送,避免无效请求
- 清晰告知用户原因
测试场景3:正常发车流程
- 等待服务器日切后(每日0次)
- 在批量自动化中发车
- 预期:
- 同步服务器端的0次记录
- 成功发送4辆车
- 发送过程中实时更新计数
- 最终显示 4/4
测试场景4:跨设备发车
- 在设备A发车2辆
- 在设备B(批量自动化)发车
- 预期:
- 设备B查询时同步设备A的2次记录
- 只发送剩余2辆
- 两设备数据一致
📋 相关错误码说明
| 错误码 | 错误信息 | 原因 | 解决方法 |
|---|---|---|---|
| 12000050 | 今日发车次数已达上限 | 服务器端已有4次发车记录 | 等待服务器日切或使用新账号 |
| 200020 | 出了点小问题 | 冷却期/状态未同步 | 已通过3秒等待修复 |
| 12000102 | 车未到终点 | 车辆还在运输中 | 等待车辆到达后收获 |
🔄 更新日志
版本: v3.10.0
日期: 2025-10-08
类型: 功能优化
修改内容:
- ✅ 查询车辆时同步服务器端的
sendCount - ✅ 刷新车辆后再次同步
sendCount - ✅ 发送前最后一次确认并同步
sendCount - ✅ 发送前提前检测发车次数上限
- ✅ 增强错误处理,区分 12000050 和 200020
- ✅ 优化日志输出,显示同步过程
影响范围:
src/stores/batchTaskStore.js-sendCar任务
解决问题:
- 客户端和服务器端发车次数不一致
- 发车次数达到上限后仍尝试发送
- 错误信息不明确
性能提升:
- 减少无效的发送请求
- 提前检测并退出,节省时间
- 日志更清晰,便于排查问题