Skip to content

Latest commit

 

History

History
217 lines (172 loc) · 6.09 KB

File metadata and controls

217 lines (172 loc) · 6.09 KB

数据存储迁移报告 - 从LocalStorage到API数据库交互

背景

根据用户要求,所有商店页面和个人资料页面的数据交互都必须基于数据库交互,不再使用localStorage等本地数据存储。

修改内容

1. 移除apiService中的localStorage回退机制

文件: src/services/apiService.ts

修改前:

  • 包含了cloudStorage兼容性接口,使用localStorage作为回退方案

修改后:

  • 移除了所有localStorage回退机制
  • 确保所有数据操作都通过API进行
  • 只保留token的localStorage存储(这是认证的标准做法)
// 移除原有的cloudStorage接口,确保所有数据交互都通过API完成
// 不再使用localStorage作为回退方案,所有数据操作都必须通过数据库完成

2. 重构cloudStorage服务

文件: src/services/cloudStorage.ts

修改前:

  • 大量使用localStorage和sessionStorage
  • 复杂的本地数据同步逻辑
  • 设备ID生成等本地存储功能

修改后:

  • 完全基于API的数据操作
  • 所有方法都重定向到apiService
  • 移除所有localStorage相关代码

主要改进:

// 获取用户数据 - 只从API获取
async getUsers(): Promise<CloudStorageResponse<any[]>> {
  try {
    const response = await apiService.getUserProfile();
    if (response.success && response.data) {
      return {
        success: true,
        data: [response.data.user],
      };
    }
    // ... 错误处理
  }
}

// 保存用户数据 - 只通过API保存
async saveUsers(users: any[]): Promise<CloudStorageResponse<any[]>> {
  if (!users.length) {
    return { success: false, error: '没有用户数据需要保存' };
  }

  try {
    const user = users[0];
    const response = await apiService.updateUserProfile({
      avatar: user.avatar,
      avatarFrame: user.avatarFrame,
      coins: user.coins,
      experience: user.experience,
      level: user.level,
      totalScore: user.totalScore,
      gamesCompleted: user.gamesCompleted,
      ownedItems: user.ownedItems,
      achievements: user.achievements,
      bestTimes: user.bestTimes,
    });
    // ... 处理响应
  }
}

3. 增强商店购买数据同步

文件: src/pages/Shop.tsx

改进:

  • 购买成功后增加更详细的日志记录
  • 确保用户数据立即从服务器重新获取
  • 添加错误处理和调试信息
if (response.success) {
  // 更新商店物品状态
  const updatedItems = shopItems.map(shopItem => 
    shopItem.id === item.id ? { ...shopItem, owned: true } : shopItem
  );
  setShopItems(updatedItems);

  // 刷新用户数据
  const userResponse = await apiService.getUserProfile();
  if (userResponse.success && userResponse.data) {
    const convertedUser = {
      ...userResponse.data.user,
      createdAt: new Date(userResponse.data.user.createdAt),
      lastLoginAt: new Date(userResponse.data.user.lastLoginAt),
    };
    setAuthenticatedUser(convertedUser, apiService.getToken() || '');
    console.log('购买成功,用户数据已更新');
    console.log('更新后的用户拥有物品:', convertedUser.ownedItems);
  } else {
    console.error('获取用户数据失败:', userResponse.error);
  }
}

4. 个人资料页面调试功能

文件: src/pages/Profile.tsx

新增功能:

  • 开发模式下的用户数据调试显示
  • 手动刷新用户数据按钮(仅开发模式)
  • 实时监听用户拥有物品变化

调试信息包括:

  • 用户ID
  • 金币数量
  • 拥有物品数量和详细列表
  • 当前头像和头像框设置

技术要点

1. 数据流向

用户操作 → API请求 → 数据库 → API响应 → 前端状态更新

2. 错误处理

  • 所有API调用都包含错误处理
  • 网络错误和业务错误的区分
  • 用户友好的错误提示

3. 状态同步

  • 购买物品后立即刷新用户数据
  • AuthContext作为全局状态管理
  • 组件间数据一致性保证

4. 开发调试

  • 开发模式下的详细日志
  • 实时数据状态监控
  • 手动数据刷新功能

验证步骤

1. 商店购买测试

  1. 登录用户账户
  2. 在商店购买物品
  3. 查看浏览器控制台日志
  4. 确认没有localStorage相关操作
  5. 验证个人资料页面立即显示购买物品

2. 数据同步测试

  1. 在个人资料页面查看调试信息
  2. 使用"刷新用户数据"按钮
  3. 确认所有数据都来自API
  4. 验证跨页面数据一致性

3. 网络请求监控

  1. 打开浏览器开发者工具Network面板
  2. 进行购买和页面切换操作
  3. 确认所有数据请求都指向后端API
  4. 验证没有localStorage读写操作

不再使用的功能

1. localStorage数据存储

  • localStorage.getItem('puzzle_users')
  • localStorage.setItem('puzzle_users', ...)
  • ❌ 本地用户数据缓存
  • ❌ 设备ID生成和存储

2. 数据合并逻辑

  • ❌ 本地与云端数据冲突解决
  • ❌ sessionStorage云端模拟
  • ❌ 跨设备数据同步(本地实现)

3. 回退机制

  • ❌ API失败时的localStorage回退
  • ❌ 离线数据存储

保留的localStorage使用

认证Token存储

  • localStorage.getItem('puzzle_auth_token') - 用于保持登录状态
  • localStorage.setItem('puzzle_auth_token', token) - 保存认证令牌
  • localStorage.removeItem('puzzle_auth_token') - 退出登录时清除

说明: 认证token的localStorage存储是Web应用的标准做法,用于在页面刷新后保持用户登录状态。

后续建议

1. 监控和日志

  • 在生产环境中移除调试信息
  • 添加API请求性能监控
  • 实现错误日志收集

2. 缓存策略

  • 考虑实现适当的API响应缓存
  • 避免频繁的相同API请求
  • 实现数据过期机制

3. 离线支持

  • 如需离线功能,考虑使用Service Worker
  • 实现网络状态检测
  • 提供离线模式提示

总结

本次修改确保了所有用户数据交互都通过API与数据库进行,彻底移除了localStorage作为数据存储的使用(除了必要的认证token)。这提高了数据的一致性和可靠性,同时为多设备同步和实时数据更新提供了更好的基础。