# 俱乐部信息自动刷新 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` 标志 --- ## 🔧 代码实现 ### 新增导入 ```javascript import { ref, computed, onMounted, onUnmounted, watch } from 'vue' ``` ### 新增状态 ```javascript const clubInfoFetched = ref(false) let wsCheckInterval = null let checkCount = 0 const maxCheckCount = 10 ``` ### onMounted 生命周期 ```javascript 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 清理 ```javascript onUnmounted(() => { console.log('🏛️ [俱乐部] ClubInfo 组件卸载,清理定时器') if (wsCheckInterval) { clearInterval(wsCheckInterval) } }) ``` ### Token 切换监听 ```javascript 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/10,WebSocket 状态: connecting 🏛️ [俱乐部] 检查 2/10,WebSocket 状态: connecting 🏛️ [俱乐部] 检查 3/10,WebSocket 状态: connected 🏛️ [俱乐部] WebSocket 已连接,准备自动刷新 🏛️ [俱乐部] 执行自动刷新 📤 发送消息: legion_getinfo {} 📥 收到响应: legion_getinforesp { info: {...} } 🏛️ 军团信息已更新: { hasInfo: true, clubName: "xxx俱乐部", memberCount: 30 } 🏛️ [俱乐部] 已成功获取数据,停止检查 ``` ### Token 未选中 ``` 🏛️ [俱乐部] ClubInfo 组件已挂载 🏛️ [俱乐部] 检查 1/10,Token 未选中,继续等待... 🏛️ [俱乐部] 检查 2/10,Token 未选中,继续等待... 🏛️ [俱乐部] 检查 3/10,Token 未选中,继续等待... ... 🏛️ [俱乐部] 超过最大检查次数,停止自动刷新 ``` ### WebSocket 连接失败 ``` 🏛️ [俱乐部] ClubInfo 组件已挂载 🏛️ [俱乐部] 检查 1/10,WebSocket 状态: connecting 🏛️ [俱乐部] 检查 2/10,WebSocket 状态: connecting 🏛️ [俱乐部] 检查 3/10,WebSocket 状态: error 🏛️ [俱乐部] 检查 4/10,WebSocket 状态: 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. ✅ 新增 `onMounted`、`onUnmounted`、`watch` 导入 2. ✅ 新增 `clubInfoFetched` 状态标志 3. ✅ 实现 WebSocket 状态轮询检查 4. ✅ 实现自动刷新逻辑 5. ✅ 实现定时器清理 6. ✅ 实现 Token 切换监听 --- ## 🧪 测试验证 ### 测试用例1:正常自动刷新 **前置条件**: - Token 已选中 - WebSocket 已连接 **操作步骤**: 1. 进入"游戏功能"页面 2. 等待 2-3 秒 **预期结果**: - ✅ 俱乐部信息自动加载 - ✅ 显示俱乐部名称、成员数等信息 - ✅ 控制台输出自动刷新日志 ### 测试用例2:Token 未选中 **前置条件**: - 未选中任何 Token **操作步骤**: 1. 进入"游戏功能"页面 2. 等待 10 秒 **预期结果**: - ✅ 显示"暂无俱乐部"空状态 - ✅ 控制台提示"Token 未选中" - ✅ 10 秒后停止检查 ### 测试用例3:WebSocket 连接中 **前置条件**: - Token 已选中 - WebSocket 正在连接中 **操作步骤**: 1. 进入"游戏功能"页面 2. 观察自动刷新过程 **预期结果**: - ✅ 持续检查 WebSocket 状态 - ✅ 连接成功后自动刷新 - ✅ 俱乐部信息正确显示 ### 测试用例4:Token 切换 **前置条件**: - 已有多个 Token **操作步骤**: 1. 进入"游戏功能"页面 2. 等待俱乐部信息加载完成 3. 切换到另一个 Token **预期结果**: - ✅ `clubInfoFetched` 标志重置 - ✅ 允许下次进入页面时重新自动刷新 ### 测试用例5:快速切换页面 **操作步骤**: 1. 进入"游戏功能"页面 2. 立即切换到其他页面 **预期结果**: - ✅ 组件卸载,定时器被清理 - ✅ 无内存泄漏 - ✅ 无错误日志 --- ## 💡 使用说明 ### 自动刷新 1. 确保已选中 Token 2. 进入"游戏功能"页面 3. 等待 2-3 秒,俱乐部信息自动加载 ### 手动刷新 1. 点击右上角"刷新"按钮 2. 立即重新获取俱乐部信息 ### 查看调试日志 打开浏览器控制台,查看以 `🏛️ [俱乐部]` 开头的日志 --- ## 🔮 后续优化方向 ### 1. 统一自动刷新机制(P1) 目前月度任务和俱乐部信息都使用相似的逻辑,可以抽取为公共 composable: ```javascript // 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 **状态**:✅ 完成并可测试 🎊 **现在刷新页面,进入游戏功能,俱乐部信息应该自动加载了!** 🚀