Files
xyzw_web_helper/MD说明文件夹/俱乐部信息自动刷新v2.1.2.md
2025-10-17 20:56:50 +08:00

10 KiB
Raw Blame History

俱乐部信息自动刷新 v2.1.2

📅 更新时间

2025-10-12 23:15

🎯 问题描述

现象

进入"游戏功能"页面后,俱乐部信息不会自动刷新,需要手动点击"刷新"按钮才能加载数据。

原因分析

ClubInfo.vue 组件缺少自动刷新逻辑:

  • 没有在 onMounted 时调用 refreshClub()
  • 没有检查 WebSocket 连接状态
  • 没有处理异步初始化时序问题

解决方案

实现逻辑

参考月度任务的成功实现,采用相同的自动刷新机制:

  1. 延迟启动500ms

    • 等待组件完全挂载
    • 避免过早调用导致失败
  2. 轮询检查 WebSocket 状态(每秒一次)

    • 检查 selectedToken 是否存在
    • 检查 WebSocket 连接状态是否为 connected
    • 最多检查 10 次10 秒超时)
  3. 连接成功后自动刷新

    • 延迟 1 秒执行 refreshClub()
    • 设置 clubInfoFetched 标志,防止重复刷新
  4. Token 切换监听

    • 监听 selectedToken 变化
    • 切换 Token 时重置 clubInfoFetched 标志

🔧 代码实现

新增导入

import { ref, computed, onMounted, onUnmounted, watch } from 'vue'

新增状态

const clubInfoFetched = ref(false)
let wsCheckInterval = null
let checkCount = 0
const maxCheckCount = 10

onMounted 生命周期

onMounted(() => {
  console.log('🏛️ [俱乐部] ClubInfo 组件已挂载')
  
  // 延迟 500ms 后开始检查 WebSocket 连接状态
  setTimeout(() => {
    wsCheckInterval = setInterval(() => {
      checkCount++
      
      if (clubInfoFetched.value) {
        console.log('🏛️ [俱乐部] 已成功获取数据,停止检查')
        clearInterval(wsCheckInterval)
        return
      }
      
      if (checkCount > maxCheckCount) {
        console.warn('🏛️ [俱乐部] 超过最大检查次数,停止自动刷新')
        clearInterval(wsCheckInterval)
        return
      }
      
      const token = tokenStore.selectedToken
      if (!token) {
        console.log('🏛️ [俱乐部] Token 未选中,继续等待...')
        return
      }
      
      const status = tokenStore.getWebSocketStatus(token.id)
      console.log(`🏛️ [俱乐部] 检查 ${checkCount}/${maxCheckCount}WebSocket 状态: ${status}`)
      
      if (status === 'connected') {
        console.log('🏛️ [俱乐部] WebSocket 已连接,准备自动刷新')
        
        // 连接成功后延迟 1 秒刷新,确保组件完全初始化
        setTimeout(() => {
          console.log('🏛️ [俱乐部] 执行自动刷新')
          refreshClub()
          clubInfoFetched.value = true
        }, 1000)
        
        clearInterval(wsCheckInterval)
      }
    }, 1000) // 每秒检查一次
  }, 500)
})

onUnmounted 清理

onUnmounted(() => {
  console.log('🏛️ [俱乐部] ClubInfo 组件卸载,清理定时器')
  if (wsCheckInterval) {
    clearInterval(wsCheckInterval)
  }
})

Token 切换监听

watch(() => tokenStore.selectedToken, (newToken, oldToken) => {
  if (newToken?.id !== oldToken?.id) {
    console.log('🏛️ [俱乐部] Token 切换,重置状态')
    clubInfoFetched.value = false
  }
})

🔍 工作流程

时序图

用户进入页面
    ↓
组件 onMounted (延迟 500ms)
    ↓
开始轮询检查 (每秒一次)
    ↓
检查 Token 是否存在? ───No──→ 继续等待
    ↓ Yes
检查 WebSocket 状态?
    ↓ connected
延迟 1 秒执行刷新
    ↓
调用 refreshClub()
    ↓
发送 legion_getinfo 命令
    ↓
接收 legion_getinforesp 响应
    ↓
更新 gameData.legionInfo
    ↓
UI 自动刷新computed 响应式)
    ↓
设置 clubInfoFetched = true
    ↓
停止轮询

📊 调试日志示例

正常流程

🏛️ [俱乐部] ClubInfo 组件已挂载
🏛️ [俱乐部] 检查 1/10WebSocket 状态: connecting
🏛️ [俱乐部] 检查 2/10WebSocket 状态: connecting
🏛️ [俱乐部] 检查 3/10WebSocket 状态: connected
🏛️ [俱乐部] WebSocket 已连接,准备自动刷新
🏛️ [俱乐部] 执行自动刷新
📤 发送消息: legion_getinfo {}
📥 收到响应: legion_getinforesp { info: {...} }
🏛️ 军团信息已更新: { hasInfo: true, clubName: "xxx俱乐部", memberCount: 30 }
🏛️ [俱乐部] 已成功获取数据,停止检查

Token 未选中

🏛️ [俱乐部] ClubInfo 组件已挂载
🏛️ [俱乐部] 检查 1/10Token 未选中,继续等待...
🏛️ [俱乐部] 检查 2/10Token 未选中,继续等待...
🏛️ [俱乐部] 检查 3/10Token 未选中,继续等待...
...
🏛️ [俱乐部] 超过最大检查次数,停止自动刷新

WebSocket 连接失败

🏛️ [俱乐部] ClubInfo 组件已挂载
🏛️ [俱乐部] 检查 1/10WebSocket 状态: connecting
🏛️ [俱乐部] 检查 2/10WebSocket 状态: connecting
🏛️ [俱乐部] 检查 3/10WebSocket 状态: error
🏛️ [俱乐部] 检查 4/10WebSocket 状态: error
...
🏛️ [俱乐部] 超过最大检查次数,停止自动刷新

🎯 关键参数

参数 说明
初始延迟 500ms 组件挂载后延迟启动检查
检查间隔 1000ms 每秒检查一次 WebSocket 状态
最大检查次数 10 次 超过 10 次后放弃自动刷新
刷新延迟 1000ms WebSocket 连接后延迟刷新

总超时时间

初始延迟 + (检查间隔 × 最大检查次数) = 500ms + (1000ms × 10) = 10.5s

🆚 与月度任务的对比

相同点

  • 采用相同的轮询检查机制
  • 相同的延迟策略500ms + 1000ms
  • 相同的超时保护10 次检查)
  • 相同的状态标志(防止重复刷新)
  • 相同的 Token 切换监听

不同点

特性 月度任务 俱乐部信息
标志名称 monthTaskFetched clubInfoFetched
日志前缀 [月度任务] [俱乐部]
刷新函数 fetchMonthlyActivity() refreshClub()
命令名称 activity_get legion_getinfo
响应名称 activity_getresp legion_getinforesp

📋 修改文件清单

已修改文件1个

src/components/ClubInfo.vue

变更内容

  1. 新增 onMountedonUnmountedwatch 导入
  2. 新增 clubInfoFetched 状态标志
  3. 实现 WebSocket 状态轮询检查
  4. 实现自动刷新逻辑
  5. 实现定时器清理
  6. 实现 Token 切换监听

🧪 测试验证

测试用例1正常自动刷新

前置条件

  • Token 已选中
  • WebSocket 已连接

操作步骤

  1. 进入"游戏功能"页面
  2. 等待 2-3 秒

预期结果

  • 俱乐部信息自动加载
  • 显示俱乐部名称、成员数等信息
  • 控制台输出自动刷新日志

测试用例2Token 未选中

前置条件

  • 未选中任何 Token

操作步骤

  1. 进入"游戏功能"页面
  2. 等待 10 秒

预期结果

  • 显示"暂无俱乐部"空状态
  • 控制台提示"Token 未选中"
  • 10 秒后停止检查

测试用例3WebSocket 连接中

前置条件

  • Token 已选中
  • WebSocket 正在连接中

操作步骤

  1. 进入"游戏功能"页面
  2. 观察自动刷新过程

预期结果

  • 持续检查 WebSocket 状态
  • 连接成功后自动刷新
  • 俱乐部信息正确显示

测试用例4Token 切换

前置条件

  • 已有多个 Token

操作步骤

  1. 进入"游戏功能"页面
  2. 等待俱乐部信息加载完成
  3. 切换到另一个 Token

预期结果

  • clubInfoFetched 标志重置
  • 允许下次进入页面时重新自动刷新

测试用例5快速切换页面

操作步骤

  1. 进入"游戏功能"页面
  2. 立即切换到其他页面

预期结果

  • 组件卸载,定时器被清理
  • 无内存泄漏
  • 无错误日志

💡 使用说明

自动刷新

  1. 确保已选中 Token
  2. 进入"游戏功能"页面
  3. 等待 2-3 秒,俱乐部信息自动加载

手动刷新

  1. 点击右上角"刷新"按钮
  2. 立即重新获取俱乐部信息

查看调试日志

打开浏览器控制台,查看以 🏛️ [俱乐部] 开头的日志


🔮 后续优化方向

1. 统一自动刷新机制P1

目前月度任务和俱乐部信息都使用相似的逻辑,可以抽取为公共 composable

// composables/useAutoRefresh.js
export function useAutoRefresh(options) {
  const { 
    refreshFn,      // 刷新函数
    checkInterval = 1000,  // 检查间隔
    maxCheckCount = 10,    // 最大检查次数
    initialDelay = 500,    // 初始延迟
    refreshDelay = 1000,   // 刷新延迟
    logPrefix = '自动刷新'  // 日志前缀
  } = options
  
  // ... 通用逻辑
}

// 使用
const { start, stop } = useAutoRefresh({
  refreshFn: refreshClub,
  logPrefix: '[俱乐部]'
})

2. 智能重试机制P2

  • 刷新失败时自动重试
  • 指数退避策略
  • 最大重试次数限制

3. 加载状态提示P2

  • 显示"正在加载俱乐部信息..."
  • 显示加载进度
  • 加载失败提示

4. 数据缓存P3

  • 缓存俱乐部信息到 localStorage
  • 离线模式下显示缓存数据
  • 定期刷新缓存

🐛 已知问题

问题1重复刷新

现象:在某些情况下可能触发多次刷新

原因

  • watch 监听可能触发额外刷新
  • 手动点击刷新按钮

解决方案

  • 使用 clubInfoFetched 标志防止重复
  • 后续可添加防抖/节流

问题2检查次数固定

现象:超时时间固定为 10 秒

影响

  • 网络慢时可能不够
  • 网络快时有浪费

后续优化

  • 根据网络状态动态调整
  • 提供用户配置选项

📈 性能影响

资源占用

  • CPU:极低(每秒一次检查,几乎可忽略)
  • 内存:极低(几个状态变量)
  • 网络1 次俱乐部信息请求

优化措施

  • 成功后立即停止轮询
  • 超时后自动停止
  • 组件卸载时清理定时器
  • 使用 setInterval 而非递归 setTimeout

更新时间2025-10-12 23:15
开发人员Claude Sonnet 4.5
状态 完成并可测试

🎊 现在刷新页面,进入游戏功能,俱乐部信息应该自动加载了! 🚀