wuzj 1 day ago
parent
commit
8ef67813eb
5 changed files with 371 additions and 295 deletions
  1. 2 0
      src/app.ts
  2. 145 54
      src/components/RoomCode/index.vue
  3. 17 94
      src/pages/room/waiting/index.vue
  4. 95 8
      src/services/user.ts
  5. 112 139
      src/stores/user.ts

+ 2 - 0
src/app.ts

@@ -17,6 +17,7 @@ const App = createApp({
         env: Taro.cloud.DYNAMIC_CURRENT_ENV, 
         traceUser: true
       })
+      Taro.removeStorageSync('userInfo');
       console.log('已启用微信云开发默认环境')
     }
     
@@ -27,6 +28,7 @@ const App = createApp({
     // 初始化 TabBar 状态
     tabBarStore.updateSelected()
     
+    
     // 获取用户信息
     userStore.initUser()
   },

+ 145 - 54
src/components/RoomCode/index.vue

@@ -1,69 +1,160 @@
 <template>
-    <view class="room-code">
-      <view class="room-code__title">房间码</view>
-      <view class="room-code__value">{{ code }}</view>
-      <view class="room-code__actions">
-        <nut-button size="small" type="primary" @click="handleShare">分享房间</nut-button>
-        <nut-button size="small" plain @click="handleCopy">复制</nut-button>
-      </view>
+  <view class="room-code">
+    <view class="room-code__title">房间码</view>
+    <view class="room-code__value">{{ code }}</view>
+    <view class="room-code__actions">
+      <nut-button size="small" type="primary" @click="handleShare">分享房间</nut-button>
+      <nut-button size="small" plain @click="handleCopy">复制</nut-button>
     </view>
-  </template>
+    
+    <!-- 分享弹窗 -->
+    <nut-dialog
+      title="分享房间"
+      content="邀请好友扫描二维码加入房间"
+      v-model:visible="showDialog"
+      footer-direction="horizontal"
+    >
+      <template #footer>
+        <view class="share-dialog-content">
+          <view class="qrcode-container">
+            <image id="qrcode" class="qrcode-img" :src="qrcodeUrl" />
+          </view>
+          <view class="room-info">
+            <view class="room-id">房间号: {{ code }}</view>
+            <view class="room-password" v-if="password">
+              密码: {{ password }}
+            </view>
+          </view>
+        </view>
+      </template>
+    </nut-dialog>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { defineProps, defineEmits, ref } from 'vue';
+import Taro from '@tarojs/taro';
+import qrcodeBase64 from 'qrcode-base64';
+
+const props = defineProps({
+  code: { type: String, required: true },
+  password: { type: String, default: '' }
+});
+
+const emit = defineEmits(['share', 'copy']);
+
+// 将 showDialog 暴露给模板
+const showDialog = ref(false);
+const qrcodeUrl = ref('');
+
+// 生成二维码
+const generateQRCode = () => {
+  if (!props.code) return;
+  
+  // 构建房间链接数据
+  let roomData = `room?id=${props.code}`;
+  
+  // 如果有密码,也加入密码
+  if (props.password) {
+    roomData += `&pwd=${props.password}`;
+  }
+  
+  try {
+    // 使用qrcode-base64库生成二维码
+    qrcodeUrl.value = qrcodeBase64.generateQRCodeBase64(roomData, {
+      size: 200,
+      margin: 2,
+      color: {
+        dark: '#333333',
+        light: '#FFFFFF'
+      }
+    });
+  } catch (error) {
+    console.error('生成二维码失败:', error);
+  }
+};
+
+const handleShare = () => {
+  // 生成二维码
+  generateQRCode();
   
-  <script setup lang="ts">
-  import { defineProps, defineEmits } from 'vue';
-  import Taro from '@tarojs/taro';
+  // 显示分享弹窗
+  showDialog.value = true;
   
-  const props = defineProps({
-    code: { type: String, required: true }
+  // 触发分享事件
+  emit('share', props.code);
+};
+
+const handleCopy = () => {
+  Taro.setClipboardData({
+    data: props.code,
+    success: () => {
+      Taro.showToast({
+        title: '房间码已复制',
+        icon: 'success',
+        duration: 2000
+      });
+      emit('copy', props.code);
+    }
   });
+};
+</script>
+
+<style lang="scss">
+.room-code {
+  background-color: $background-color-gold;
+  border-radius: $border-radius-small;
+  padding: $spacing-base;
+  margin: $spacing-base 0;
+  text-align: center;
   
-  const emit = defineEmits(['share', 'copy']);
+  &__title {
+    font-size: $font-size-small;
+    color: $text-color-secondary;
+    margin-bottom: $spacing-mini;
+  }
   
-  const handleShare = () => {
-    emit('share', props.code);
-  };
+  &__value {
+    font-size: $font-size-xlarge;
+    font-weight: $font-weight-bold;
+    color: $text-color-primary;
+    letter-spacing: 2px;
+    margin-bottom: $spacing-base;
+  }
   
-  const handleCopy = () => {
-    Taro.setClipboardData({
-      data: props.code,
-      success: () => {
-        Taro.showToast({
-          title: '房间码已复制',
-          icon: 'success',
-          duration: 2000
-        });
-        emit('copy', props.code);
-      }
-    });
-  };
-  </script>
+  &__actions {
+    display: flex;
+    justify-content: center;
+    gap: $spacing-small;
+  }
+}
+
+.share-dialog-content {
+  padding: $spacing-base;
   
-  <style lang="scss">
-  .room-code {
-    background-color: $background-color-gold;
-    border-radius: $border-radius-small;
-    padding: $spacing-base;
-    margin: $spacing-base 0;
-    text-align: center;
+  .qrcode-container {
+    margin: 0 auto;
+    width: 200px;
+    height: 200px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
     
-    &__title {
-      font-size: $font-size-small;
-      color: $text-color-secondary;
-      margin-bottom: $spacing-mini;
+    .qrcode-img {
+      width: 100%;
+      height: 100%;
     }
+  }
+  
+  .room-info {
+    margin-top: $spacing-large;
+    text-align: center;
     
-    &__value {
-      font-size: $font-size-xlarge;
-      font-weight: $font-weight-bold;
+    .room-id, .room-password {
+      font-size: $font-size-base;
       color: $text-color-primary;
-      letter-spacing: 2px;
-      margin-bottom: $spacing-base;
-    }
-    
-    &__actions {
-      display: flex;
-      justify-content: center;
-      gap: $spacing-small;
+      margin-bottom: $spacing-small;
     }
   }
-  </style>
+}
+</style>

+ 17 - 94
src/pages/room/waiting/index.vue

@@ -17,6 +17,7 @@
     <!-- 房间码展示和分享 -->
     <RoomCode
       :code="currentRoom?.id || ''"
+      :password="currentRoom?.password"
       @share="handleShare"
       @copy="handleCopy"
     />
@@ -200,29 +201,6 @@
         @close="showPuzzleSelector = false"
       />
     </nut-popup>
-
-    <!-- 分享房间弹窗 -->
-    <nut-dialog
-      title="分享房间"
-      content="邀请好友扫描二维码加入房间"
-      v-model:visible="showShareDialog"
-      footer-direction="horizontal"
-    >
-      <template #footer>
-        <view class="share-dialog-content">
-          <view class="qrcode-container">
-            <!-- 将canvas标签替换为image标签 -->
-            <image id="qrcode" class="qrcode-img"></image>
-          </view>
-          <view class="room-info">
-            <view class="room-id">房间号: {{ currentRoom?.id }}</view>
-            <view class="room-password" v-if="currentRoom?.password">
-              密码: {{ currentRoom.password }}
-            </view>
-          </view>
-        </view>
-      </template>
-    </nut-dialog>
   </view>
   <Tabbar></Tabbar>
 </template>
@@ -237,7 +215,6 @@ import Tabbar from '@/components/Tabbar.vue'
 import RoomCode from '@/components/RoomCode/index.vue'
 import { RoomRole, RoomStatus } from '@/types/room'
 import { TurtleSoupDifficulty } from '@/types/games/turtlesoup'
-import qrcodeBase64 from 'qrcode-base64'
 
 // 主题和题目的数据类型
 interface CascaderOption {
@@ -331,9 +308,6 @@ export default {
     const showThemeSelector = ref(false)
     const showPuzzleSelector = ref(false)
     
-    // 分享相关
-    const showShareDialog = ref(false)
-    
     // 主题选项
     const themeOptions = ref<CascaderOption[]>([
       {
@@ -505,7 +479,6 @@ export default {
         const newStatus = !currentUserReady.value
         
         // 调用API更新准备状态
-        // 假设 roomStore 有一个 updateUserReady 方法
         await roomStore.updateUserInRoom(userStore.openid, { isReady: newStatus })
         
         Taro.hideLoading()
@@ -591,69 +564,15 @@ export default {
       }
     }
     
-    // 处理分享按钮点击
-    const handleShare = () => {
-      showShareDialog.value = true
-      
-      // 等待弹窗显示后再生成二维码
-      setTimeout(() => {
-        generateQRCode()
-      }, 300)
-    }
-    
     // 处理复制按钮点击
     const handleCopy = (code: string) => {
-      // 已在RoomCode组件中处理
       console.log('房间码已复制:', code)
     }
     
-    // 生成二维码
-    const generateQRCode = () => {
-      if (!currentRoom.value) return
-      
-      // 构建房间链接数据
-      let roomData = `room?id=${currentRoom.value.id}`
-      
-      // 如果有密码,也加入密码
-      if (currentRoom.value.password) {
-        roomData += `&pwd=${currentRoom.value.password}`
-      }
-      
-      try {
-        // 使用qrcode-base64库生成二维码
-        const qrcodeBase64Url = qrcodeBase64.generateQRCodeBase64(roomData, {
-          size: 200,
-          margin: 2,
-          color: {
-            dark: '#333333',
-            light: '#FFFFFF'
-          }
-        });
-        
-        // 获取原来的canvas元素所在的父容器
-        const container = document.getElementById('qrcode')?.parentNode;
-        
-        if (container) {
-          // 移除旧的canvas元素
-          const oldCanvas = document.getElementById('qrcode');
-          if (oldCanvas) {
-            container.removeChild(oldCanvas);
-          }
-          
-          // 创建新的img元素
-          const img = document.createElement('img');
-          img.id = 'qrcode';
-          img.className = 'qrcode-img';
-          img.src = qrcodeBase64Url;
-          img.style.width = '200px';
-          img.style.height = '200px';
-          
-          // 添加到容器中
-          container.appendChild(img);
-        }
-      } catch (error) {
-        console.error('生成二维码失败:', error);
-      }
+    // 处理分享按钮点击
+    const handleShare = (code: string) => {
+      console.log('分享房间码:', code)
+      // 这里不需要额外处理,因为RoomCode组件内部已处理了分享逻辑
     }
     
     // 页面加载时初始化
@@ -689,7 +608,6 @@ export default {
       selectedPuzzle,
       showThemeSelector,
       showPuzzleSelector,
-      showShareDialog,
       themeOptions,
       puzzleOptions,
       gameTitle,
@@ -698,11 +616,10 @@ export default {
       difficultyText,
       toggleReady,
       startGame,
-      handleShare,
       handleCopy,
+      handleShare,
       onThemeChange,
       onPuzzleChange,
-      // 添加这两个变量
       selectedThemeValue,
       selectedPuzzleValue
     }
@@ -929,6 +846,17 @@ export default {
     }
   }
   
+  .action-buttons {
+    margin-top: $spacing-large;
+    
+    .start-button, .ready-button {
+      height: 44px;
+      font-size: $font-size-medium;
+      border-radius: $border-radius-base;
+    }
+  }
+  
+  // 分享弹窗相关样式
   .share-dialog-content {
     padding: $spacing-large;
     
@@ -940,11 +868,6 @@ export default {
       justify-content: center;
       align-items: center;
       
-      .qrcode-canvas {
-        width: 100%;
-        height: 100%;
-      }
-      
       .qrcode-img {
         width: 100%;
         height: 100%;

+ 95 - 8
src/services/user.ts

@@ -2,24 +2,111 @@
 import { ensureStringId } from '@/utils/db-helper'
 import { Result, createSuccess, createError } from '@/types/result'
 import { cloudApi } from '@/api'
-import { type UserInfo } from '@/types/user'
+import { type UserInfo, UserRole } from '@/types/user'
 import { USE_MOCK } from '@/services'
+import Taro from '@tarojs/taro'
 
-// Mock用户数据
-const mockUser: UserInfo = {
+// Mock用户数据 - 扩展以包含更多字段
+const createMockUser = () => ({
   nickname: '测试用户',
   avatar: 'https://example.com/avatar.jpg',
-  openid: 'mock_openid_123456',
-}
+  openid: 'mock_openid_' + Date.now().toString().slice(-6),
+  role: UserRole.USER,
+  isRegistered: true,
+  points: 100,
+  exp: 50,
+  level: 2,
+  gameCount: 5,
+  roomCount: 3
+})
 
 export const userService = {
+  // 统一登录方法 - 新增方法处理mock/真实环境
+  async login(): Promise<Result<UserInfo>> {
+    // 判断是否为mock环境
+    if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
+      return new Promise(resolve => {
+        setTimeout(() => {
+          resolve(createSuccess(createMockUser()))
+        }, 300)
+      })
+    }
+    
+    // 真实环境
+    try {
+      const loginRes = await Taro.login()
+      if (!loginRes.code) {
+        return createError('登录失败')
+      }
+      
+      const result = await this.getOpenId(loginRes.code)
+      if (!result.success || !result.data) {
+        return createError(result.message || '获取OpenID失败')
+      }
+      
+      // 返回包含openid的用户信息
+      return createSuccess({
+        openid: result.data.openid,
+        nickname: '',
+        avatar: '',
+        role: UserRole.USER
+      })
+    } catch (error) {
+      console.error('登录失败:', error)
+      return createError(error.message || '登录失败')
+    }
+  },
+  
+  // 统一注册方法 - 新增方法处理mock/真实环境
+  async register(openid: string): Promise<Result<UserInfo>> {
+    // 判断是否为mock环境
+    if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
+      return new Promise(resolve => {
+        setTimeout(() => {
+          resolve(createSuccess(createMockUser()))
+        }, 300)
+      })
+    }
+    
+    // 真实环境
+    try {
+      const profileRes = await Taro.getUserProfile({
+        desc: '用于完善用户资料'
+      })
+      
+      if (!profileRes.userInfo) {
+        return createError('获取用户信息失败')
+      }
+      
+      // 构建用户信息
+      const userData: UserInfo = {
+        openid,
+        nickname: profileRes.userInfo.nickName,
+        avatar: profileRes.userInfo.avatarUrl,
+        role: UserRole.USER
+      }
+      
+      // 保存到云端
+      await this.saveUserToCloud(userData)
+      
+      // 返回完整的用户信息
+      return createSuccess({
+        ...userData,
+        isRegistered: true
+      })
+    } catch (error) {
+      console.error('注册失败:', error)
+      return createError(error.message || '注册失败')
+    }
+  },
+  
   // 获取用户信息
   async getUserInfo(): Promise<Result<UserInfo>> {
     // 如果在开发环境或非小程序环境,使用Mock数据
     if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
       return new Promise(resolve => {
         setTimeout(() => {
-          resolve(createSuccess(mockUser))
+          resolve(createSuccess(createMockUser()))
         }, 300)
       })
     }
@@ -29,7 +116,7 @@ export const userService = {
       .then(result => {
         // 如果没有返回数据,使用mock数据
         if (result.success && !result.data) {
-          return createSuccess(mockUser)
+          return createSuccess(createMockUser())
         }
         return result
       })
@@ -44,7 +131,7 @@ export const userService = {
     // 如果在开发环境或非小程序环境,使用Mock数据
     if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
       return createSuccess({ 
-        openid: 'mock_openid_' + Date.now() 
+        openid: 'mock_openid_' + Date.now().toString().slice(-6)
       })
     }
     

+ 112 - 139
src/stores/user.ts

@@ -1,32 +1,34 @@
-// stores/user.ts - 管理用户信息、登录状态、角色权限等
+// stores/user.ts
 import { defineStore } from 'pinia'
 import Taro from '@tarojs/taro'
-import { userService} from '@/services/user'
+import { userService } from '@/services/user'
 import { type UserInfo, UserRole } from '@/types/user'
 import { ref, computed } from 'vue'
 
 export const useUserStore = defineStore('user', () => {
-  // 基本状态
+  // 基本用户信息
   const openid = ref('')
   const nickname = ref('')
   const avatar = ref('')
-  const role = ref<UserRole | undefined>(UserRole.USER)
+  const role = ref<UserRole>(UserRole.USER)
   const isRegistered = ref(false)
+  
+  // 当前状态
   const currentRoom = ref<string | null>(null)
   const currentGameId = ref<string | null>(null)
   const loading = ref(false)
   const error = ref<string | null>(null)
   
   // 经验值系统
-  const points = ref(0)      // 积分
-  const exp = ref(0)         // 经验值
-  const level = ref(1)       // 等级
-  const nextLevelExp = ref(100) // 下一级所需经验
+  const points = ref(0)
+  const exp = ref(0)
+  const level = ref(1)
+  const nextLevelExp = ref(100)
   
   // 游戏统计数据
-  const gameCount = ref(0)   // 参与游戏数量
-  const roomCount = ref(0)   // 创建房间数量
-  
+  const gameCount = ref(0)
+  const roomCount = ref(0)
+
   // 计算属性
   const userInfo = computed<UserInfo>(() => ({
     openid: openid.value,
@@ -35,35 +37,33 @@ export const useUserStore = defineStore('user', () => {
     role: role.value
   }))
   
-  // 经验值百分比
   const expPercentage = computed(() => {
     return (exp.value / nextLevelExp.value) * 100
   })
-  
-  // 保存用户状态到本地存储
+
+  // 保存/加载用户数据
   function saveUserToStorage() {
     const userData = {
       openid: openid.value,
       nickname: nickname.value,
       avatar: avatar.value,
       role: role.value,
-      currentRoom: currentRoom.value,
       isRegistered: isRegistered.value,
-      // 经验值系统数据
+      currentRoom: currentRoom.value,
+      currentGameId: currentGameId.value,
       points: points.value,
       exp: exp.value,
       level: level.value,
       nextLevelExp: nextLevelExp.value,
-      // 统计数据
       gameCount: gameCount.value,
       roomCount: roomCount.value
     }
     
     Taro.setStorageSync('userInfo', JSON.stringify(userData))
+    console.log('userData', userData)
     return userData
   }
   
-  // 从本地存储加载用户状态
   function loadUserFromStorage(): boolean {
     try {
       const userInfo = Taro.getStorageSync('userInfo')
@@ -76,17 +76,17 @@ export const useUserStore = defineStore('user', () => {
       role.value = data.role || UserRole.USER
       isRegistered.value = !!data.isRegistered
       currentRoom.value = data.currentRoom || null
+      currentGameId.value = data.currentGameId || null
       
-      // 加载经验值系统数据
       points.value = data.points || 0
       exp.value = data.exp || 0
       level.value = data.level || 1
       nextLevelExp.value = data.nextLevelExp || 100
       
-      // 加载统计数据
       gameCount.value = data.gameCount || 0
       roomCount.value = data.roomCount || 0
       
+      console.log('loadUserFromStorage', userInfo)
       return true
     } catch (error) {
       console.error('加载用户信息失败:', error)
@@ -94,26 +94,46 @@ export const useUserStore = defineStore('user', () => {
     }
   }
   
-  // 初始化用户信息
+  // 设置用户数据 - 用于从API设置完整用户数据
+  function setUserData(userData: any) {
+    if (!userData) return
+    
+    openid.value = userData.openid || openid.value
+    nickname.value = userData.nickname || nickname.value
+    avatar.value = userData.avatar || avatar.value
+    role.value = userData.role || role.value
+    isRegistered.value = userData.isRegistered !== undefined ? userData.isRegistered : isRegistered.value
+    
+    // 设置可选的扩展数据
+    if (userData.points !== undefined) points.value = userData.points
+    if (userData.exp !== undefined) exp.value = userData.exp
+    if (userData.level !== undefined) level.value = userData.level
+    if (userData.gameCount !== undefined) gameCount.value = userData.gameCount
+    if (userData.roomCount !== undefined) roomCount.value = userData.roomCount
+    
+    saveUserToStorage()
+  }
+  
+  // 初始化用户
   async function initUser() {
     loading.value = true
     error.value = null
-    
+
     try {
       // 1. 尝试从本地存储加载
       const localDataLoaded = loadUserFromStorage()
       
-      // 2. 如果本地有数据且已注册,直接返回成功
+      // 2. 如果已有数据且注册,直接返回
       if (localDataLoaded && isRegistered.value) {
         return true
       }
       
-      // 3. 如果本地有openid但未注册,保持现状
-      if (localDataLoaded && openid.value && !isRegistered.value) {
+      // 3. 如果有openid但未注册,保持现状
+      if (localDataLoaded && openid.value) {
         return true
       }
       
-      // 4. 否则,进行静默登录获取openid
+      // 4. 否则,行静默登录获取openid
       return await silentLogin()
     } catch (e) {
       console.error('初始化用户失败:', e)
@@ -126,32 +146,22 @@ export const useUserStore = defineStore('user', () => {
   
   // 静默登录 - 仅获取openid
   async function silentLogin() {
-    loading.value = true
-    error.value = null
-    
     try {
-      const loginRes = await Taro.login()
-      if (!loginRes.code) {
-        error.value = '登录失败'
-        return false
-      }
+      // userService处理mock或真实环境逻辑
+      const result = await userService.login()
       
-      const result = await userService.getOpenId(loginRes.code)
-      if (!result.success || !result.data) {
-        error.value = result.message || '获取OpenID失败'
+      if (result.success && result.data) {
+        // 设置用户数据
+        setUserData(result.data)
+        return true
+      } else {
+        error.value = result.message || '登录失败'
         return false
       }
-      
-      // 设置openid
-      openid.value = result.data.openid
-      saveUserToStorage()
-      return true
     } catch (e) {
       console.error('静默登录失败:', e)
       error.value = '静默登录失败'
       return false
-    } finally {
-      loading.value = false
     }
   }
   
@@ -167,43 +177,16 @@ export const useUserStore = defineStore('user', () => {
         if (!loginSuccess) return false
       }
       
-      // 微信环境使用getUserProfile
-      if (process.env.TARO_ENV === 'weapp') {
-        const profileRes = await Taro.getUserProfile({
-          desc: '用于完善用户资料'
-        })
-        
-        if (!profileRes.userInfo) {
-          error.value = '获取用户信息失败'
-          return false
-        }
-        
-        // 更新本地状态
-        nickname.value = profileRes.userInfo.nickName
-        avatar.value = profileRes.userInfo.avatarUrl
-        isRegistered.value = true
-        
-        // 保存到本地存储
-        saveUserToStorage()
-        
-        // 同步到云端 - 使用Service层处理
-        await userService.saveUserToCloud({
-          openid: openid.value,
-          nickname: nickname.value,
-          avatar: avatar.value,
-          role: role.value
-        })
-        
+      // 调用userService处理注册逻辑(内部处理mock/真实环境)
+      const result = await userService.register(openid.value)
+      
+      if (result.success && result.data) {
+        // 设置用户数据
+        setUserData(result.data)
         return true
       } else {
-        // 非微信环境模拟注册
-        nickname.value = '模拟用户_' + Date.now().toString().slice(-4)
-        avatar.value = 'https://example.com/avatar.jpg'
-        isRegistered.value = true
-        
-        // 保存到本地
-        saveUserToStorage()
-        return true
+        error.value = result.message || '注册失败'
+        return false
       }
     } catch (e) {
       console.error('用户注册失败:', e)
@@ -214,94 +197,83 @@ export const useUserStore = defineStore('user', () => {
     }
   }
   
-  // 设置用户角色
-  function setRole(newRole: UserRole) {
-    role.value = newRole
-    saveUserToStorage()
-  }
-  
-  // 设置当前房间
-  function setCurrentRoom(roomId: string) {
-    currentRoom.value = roomId
-    saveUserToStorage()
-  }
-  
-  // 退出登录
-  function logout() {
-    openid.value = ''
-    nickname.value = ''
-    avatar.value = ''
-    isRegistered.value = false
-    currentRoom.value = null
-    currentGameId.value = null
-    
-    // 清除本地存储
-    Taro.removeStorageSync('userInfo')
-  }
-  
-  // 设置当前游戏
-  function setCurrentGame(gameId: string | null) {
-    currentGameId.value = gameId
-  }
-  
-  // 重置用户角色到普通用户
-  function resetToNormalUser() {
-    role.value = UserRole.USER
-    saveUserToStorage()
-  }
-  
-  // 清除房间和游戏信息
-  function clearGameSession() {
-    currentRoom.value = null
-    currentGameId.value = null
-    saveUserToStorage()
-  }
-  
-  // 经验值系统相关方法
-  
-  // 增加积分
+  // 经验值系统
   function addPoints(amount: number) {
     points.value += amount
     saveUserToStorage()
   }
   
-  // 增加经验值
   function addExp(amount: number) {
     exp.value += amount
-    
-    // 检查是否升级
     checkLevelUp()
-    
     saveUserToStorage()
     return { level: level.value, exp: exp.value, nextLevelExp: nextLevelExp.value }
   }
   
-  // 检查是否升级
   function checkLevelUp() {
     while (exp.value >= nextLevelExp.value) {
-      // 升级
       level.value++
       exp.value -= nextLevelExp.value
-      
-      // 调整下一级所需经验值 (每级增加20%)
       nextLevelExp.value = Math.floor(nextLevelExp.value * 1.2)
     }
   }
   
-  // 统计数据相关方法
-  
-  // 记录参与游戏
+  // 统计数据
   function recordGameParticipation() {
     gameCount.value++
     saveUserToStorage()
   }
   
-  // 记录创建房间
   function recordRoomCreation() {
     roomCount.value++
     saveUserToStorage()
   }
   
+  // 简单setter方法
+  function setCurrentRoom(roomId: string) {
+    currentRoom.value = roomId
+    saveUserToStorage()
+  }
+  
+  function setCurrentGame(gameId: string | null) {
+    currentGameId.value = gameId
+    saveUserToStorage()
+  }
+  
+  function setRole(newRole: UserRole) {
+    role.value = newRole
+    saveUserToStorage()
+  }
+  
+  // 重置/清除
+  function logout() {
+    openid.value = ''
+    nickname.value = ''
+    avatar.value = ''
+    isRegistered.value = false
+    currentRoom.value = null
+    currentGameId.value = null
+    points.value = 0
+    exp.value = 0
+    level.value = 1
+    nextLevelExp.value = 100
+    gameCount.value = 0
+    roomCount.value = 0
+    
+    Taro.removeStorageSync('userInfo')
+  }
+  
+  function resetToNormalUser() {
+    role.value = UserRole.USER
+    saveUserToStorage()
+  }
+  
+  function clearGameSession() {
+    currentRoom.value = null
+    currentGameId.value = null
+    saveUserToStorage()
+  }
+
   return {
     // 状态
     openid,
@@ -329,11 +301,12 @@ export const useUserStore = defineStore('user', () => {
     // 方法
     initUser,
     registerUser,
+    silentLogin,
     setRole,
     setCurrentRoom,
-    logout,
     setCurrentGame,
-    resetToNormalUser,  // 方法名称更新
+    logout,
+    resetToNormalUser,
     clearGameSession,
     
     // 经验值系统方法